다음 코드는 gcc 및 clang (및 기타 여러 C ++ 11 컴파일러)으로 컴파일됩니다.
#include <stdint.h>
typedef int datatype;
template <typename T>
struct to_datatype {};
template <>
struct to_datatype<int16_t> {
static constexpr datatype value = 1;
};
template <typename T>
class data {
public:
data(datatype dt = to_datatype<T>::value) {}
};
int main() {
data<char> d{to_datatype<int16_t>::value};
}
(거의) 최신 MSVC로 컴파일 할 때
> cl .\test.cpp /std:c++latest /permissive-
Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
.\test.cpp(16): error C2039: 'value': is not a member of 'to_datatype<T>'
with
[
T=char
]
.\test.cpp(16): note: see declaration of 'to_datatype<T>'
with
[
T=char
]
.\test.cpp(20): note: see reference to class template instantiation 'data<char>' being compiled
이것은 MSVC의 버그입니까? 그렇다면 C ++ 표준에서 어떤 용어가 가장 잘 묘사됩니까?
코드의 일부를
template <typename T>
class data {
public:
data(datatype dt) {}
data() : data(to_datatype<T>::value) {}
};
어쨌든 부드럽게 컴파일됩니다.
답변
MSVC가 코드를 받아들이지 않는 것이 잘못되었다고 말할 것입니다.
C ++ 17 표준 최종 드래프트의 [dcl.fct.default] / 5 에 따르면 클래스 템플릿의 멤버 함수에 대한 기본 인수의 이름 조회는 [temp.inst]의 규칙에 따라 수행됩니다.
따르면 [temp.inst / 2 클래스 템플릿 암시 실체화 멤버 함수의 기본 인자 인스턴스화 일으키지 않는하고있어서 [temp.inst / 4 의 (비 명백한 특성화 멤버 함수의 기본 인자 a) 클래스 템플릿은 호출에 의해 사용될 때 인스턴스화됩니다.
to_datatype<T>::value
코드에서 기본 인수 를 사용하는 호출이 없으므로 인스턴스화해서는 안됩니다. 그러므로의 조회에 대한 오류가 없어야 value
에 to_datatype<char>
실패한다.
(C ++ 11 표준 최종 드래프트의 관련 섹션에는 번호 매기기를 제외하고 동등한 표현이 있습니다 . 대신 [decl.fct.default] / 5 , [temp.inst] / 1 및 [temp.inst] / 3 를 참조하십시오.)