以下代码使用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的非显式特化)类模板的成员函数的默认参数在被a使用时实例化。称呼。
在代码中没有使用默认参数to_datatype<T>::value
的调用,因此不应实例化它。因此,在value
失败时,应该不会出现有关to_datatype<char>
的查找错误。
(C++ 11标准最终草案中的相关部分具有相同的措词,除了编号外,请参见[decl.fct.default]/5,[temp.inst]/1和[temp.inst]/3。)
关于c++ - MSVC中可能的编译器错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59546755/