【问题标题】:(Visual-) C++ Template type inference for string literals - VS 2010 vs VS 2017(Visual-)字符串文字的 C++ 模板类型推断 - VS 2010 与 VS 2017
【发布时间】:2018-03-31 15:59:08
【问题描述】:

在尝试为字符串文字添加模板特化时,我注意到 VS 2017 编译器和 VS 2010 编译器(均从 VS 2017 调用)之间的行为差​​异

这是有问题的代码:

#include <iostream>

template <typename T>
struct foo
{
    static const int a = -1;
};

template <size_t n>
struct foo<char[n]>
{
    static const int a = 0;
};

template <size_t n>
struct foo<const char[n]>
{
    static const int a = 1;
};

template <typename T>
int bar(const T& x)
{
#pragma message (__FUNCSIG__)
    return foo<T>::a;
}

int main()
{
    std::cout << _MSC_VER << '\n';
    std::cout << bar("a") << '\n';
}

使用 VS 2017 的默认编译器运行:

int __cdecl bar<char[2]>(const char (&)[2])
1911
0

并使用 VS 2010 编译器运行:

int __cdecl bar<const char[2]>(const char (&)[2])
1600
1

如您所见,T 被推断为旧编译器的const char[2],而char[2] 则用于新编译器。发生了什么变化?这是 Visual Studio 中的错误修复/错误,还是在 C++11/C++14 中改变了正确的行为?

尝试用tio.run(gcc和clang),看来VS 2017是对的,这样对吗?

【问题讨论】:

  • FWIW,C++ 中的字符串文字一直是 const char[N],但如果 VS 将它们设置为 char[N] 以实现 C 兼容性,这是可以理解的。

标签: c++ templates visual-c++ type-inference


【解决方案1】:

这是简单的类型匹配。

您的函数采用const T&amp;。如果我传递一个整数,T会被推导出为int,所以签名是const int&amp;。将其推断为const int 只会是多余的。

如您所见,您的参数已经作为其中的 const,所以它被匹配了。

肯定是一个 MSVC 2010 的错误,随着时间的推移已经修复,因为旧版本的 Visual Studio 的模板实现质量相当低。

【讨论】:

  • 感谢您的澄清 - 我只是想知道我是否遗漏了什么,但是阅读您的解释会使这个问题看起来很愚蠢
  • @Mathe172 您的问题格式正确且合法,因此确实没有问题。
猜你喜欢
  • 2018-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多