2017-10-19 79 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您的問題形式合理,合法,所以確實沒有問題。 –