2017-10-19 78 views
3

在尝试为字符串文字添加模板专业化时,我注意到VS 2017编译器和VS 2010编译器之间的行为差​​异从2017年VS)(Visual-)用于字符串文字的C++模板类型推断 - VS 2010 vs VS 2017

这是有问题的代码:使用默认的编译器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'; 
} 

运行:

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是正确的,这是正确的吗?

+0

FWIW,C++中的字符串文字一直是'const char [N]',但如果VS为了C兼容性而将它们作为'char [N]',这是可以理解的。 – chris

回答

1

这是简单的类型匹配。您的功能需要const T&。如果我传递一个整数,T将被推断为int,所以签名是const int&。将其推定为const int只会是多余的。你可以看到,你的参数已经作为const中的参数,所以它被匹配了。

毫无疑问,随着时间的推移,MSVC 2010的bug已经得到修复,因为老版本的visual studio的模板质量相当差。

+0

感谢您的澄清 - 我只是想知道我是否错过了任何东西,但是阅读您的解释使得问题看起来很愚蠢 – Mathe172

+0

@ Mathe172您的问题形式合理,合法,所以确实没有问题。 –