我想确认这个代码是合法的(还是不合法的?)C++17。
#include <iostream>
template<int N> inline constexpr float MyConst;
template<> inline constexpr float MyConst<1> = 1.1f;
template<> inline constexpr float MyConst<2> = 2.2f;
int main ()
{
std::cout << MyConst<1> << '\n';
return 0;
}
如果用G++和MSVC编译,我不会得到错误(并得到正确的输出),
但Intel和clang给出了一个错误:
test.cpp(3): error: missing initializer for constexpr variable
template<int N> inline constexpr float MyConst;
^
使用-std=C++17
编译(对于MSVC/std:C++17
)。
在godbolt和我的本地机器上尝试了最新的编译器。
必须立即初始化constexpr
变量。因此,myconst
的模板需要一个initialiser/definition。GCC一开始就不需要定义,这是违反规范的。如果使用变量的非专用形式,例如myconst<3>
,您将从gcc得到类似的错误:
<source>: In instantiation of 'constexpr const float MyConst<3>':
<source>:10:18: required from here
<source>:3:40: error: uninitialized 'const MyConst<3>' [-fpermissive]
3 | template<int N> inline constexpr float MyConst;
| ^~~~~~~
ASM generation compiler returned: 1
<source>: In instantiation of 'constexpr const float MyConst<3>':
<source>:10:18: required from here
<source>:3:40: error: uninitialized 'const MyConst<3>' [-fpermissive]
3 | template<int N> inline constexpr float MyConst;
|
这可以通过为MyConst提供一个初始定义来解决,例如。
// Use a "sensible default"
template<int N> inline constexpr float MyConst(0.0f);
// Provide a more general definition
template<int N> inline constexpr float MyConst = N*1.1f;
有关标准的相关部分,请参见DCL.Constexpr第1段。
constexpr说明符应仅应用于变量或变量模板的定义或函数或函数模板的声明。consteval说明符只能应用于函数或函数模板的声明。使用constexpr或consteval说明符声明的函数或静态数据成员隐式为内联函数或变量。如果函数或函数模板的任何声明具有constexpr或consteval说明符,那么它的所有声明都应包含相同的说明符。