MSVC의 가능한 컴파일러 버그 {} }; int main() { data<char> d{to_datatype<int16_t>::value}; } (거의)

다음 코드는 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코드에서 기본 인수 를 사용하는 호출이 없으므로 인스턴스화해서는 안됩니다. 그러므로의 조회에 대한 오류가 없어야 valueto_datatype<char>실패한다.

(C ++ 11 표준 최종 드래프트의 관련 섹션에는 번호 매기기를 제외하고 동등한 표현이 있습니다 . 대신 [decl.fct.default] / 5 , [temp.inst] / 1[temp.inst] / 3 를 참조하십시오.)