C++20中非类型模板参数MSVC编译失败,GCC/Clang正常,求判定
关于C++20非类型模板参数的编译器行为疑问
我学习了非类型模板参数(non-type template parameter),了解到它们必须是编译时常量。我编写了如下代码,该代码在GCC和Clang编译器下可正常编译,但在MSVC下编译失败。我使用的是C++20标准,想了解哪个编译器的行为符合标准要求。
struct C { }; template<C c> int func() { return 5; } int main() { C a{}; func<a>(); // 在GCC和Clang中编译通过,但MSVC编译失败 }
MSVC报错信息:
example.cpp <source>(11): error C2672: 'func': no matching overloaded function found <source>(5): note: could be 'int func(void)' <source>(11): note: 'func': template parameter 'c': 'a': a variable with non-static storage duration cannot be used as a non-type argument <source>(10): note: see declaration of 'a' Compiler returned: 2
解答
根据C++20标准,当非类型模板参数的类型是无用户定义构造函数、析构函数,且无任何非静态数据成员的类类型(即示例中的struct C这类“空类”)时,该类型的对象属于符合要求的结构类型值,允许作为非类型模板参数的实参,哪怕这个对象是自动存储期(非静态局部变量)的。
GCC与Clang的行为完全符合C++20标准,而MSVC的报错是不符合标准的——它错误地要求此类实参必须是静态存储期的编译时常量。
C++20标准的[temp.param]/4条款明确规定:满足特定条件的结构类型(包括无特殊成员函数、无虚函数、所有成员均为constexpr可构造的类/结构体/联合体)的对象,可以作为非类型模板参数。你的struct C完全满足这些条件,因此func<a>()的写法是合法的。
内容的提问来源于stack exchange,提问作者Vlad from Moscow
相关产品推荐
相关产品推荐

