2017-10-19 4 views
3

문자열 리터럴에 대한 템플릿 전문을 추가하는 동안 VS 2017 컴파일러와 VS 2010 컴파일러 (둘 다 호출되는 VS 2017의 기본 컴파일러를 사용하여(Visual-) C++ 문자열 리터럴에 대한 템플릿 형식 유추 - VS 2010 VS 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 2017)에서

이 문제의 코드는 은 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&입니다. 정수를 넘기는 경우 Tint으로 추론되므로 서명은 const int&이됩니다. const int으로 그것을 공제하는 것은 단지 중복 일 것입니다.

당신이 볼 수 있듯이 매개 변수가 이미 const에 들어 있기 때문에 매치됩니다.

Visual Studio의 이전 버전은 템플릿의 구현이 매우 저조했기 때문에 MSVC 2010 버그가 수정되었습니다.

+0

설명해 주셔서 고마워요. - 제가 놓친 것이 있는지 궁금 해서요.하지만 설명을 읽으면 질문이 꽤 어리 석게 보입니다. – Mathe172

+0

@ Mathe172 귀하의 질문은 정당하고 합법적이어서 문제가 없습니다. –