提问者:小点点

模板constexpr变量


我想确认这个代码是合法的(还是不合法的?)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和我的本地机器上尝试了最新的编译器。


共1个答案

匿名用户

必须立即初始化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说明符,那么它的所有声明都应包含相同的说明符。

相关问题