C++ 初始化类模板的静态constexpr成员变量

C++ 初始化类模板的静态constexpr成员变量,c++,templates,c++17,c++14,constexpr,C++,Templates,C++17,C++14,Constexpr,情况如下:一个带有模板paramint N的类Foo有一个静态成员变量float val。val的值对应于N,并且从不改变,因此我希望它是constepr 我知道初始化静态constexpr成员变量的常用方法是: //好的,但不是我想要的 模板 结构Foo{ 静态constexpr float val{0.0f}; }; 模板 constexpr float Foo::val; 但是由于val在类范围内被初始化,我不能为不同的N指定不同的val 如果val不是constexpr而是const,

情况如下:一个带有模板param
int N
的类
Foo
有一个静态成员变量
float val
val
的值对应于
N
,并且从不改变,因此我希望它是
constepr

我知道初始化静态constexpr成员变量的常用方法是:

//好的,但不是我想要的
模板
结构Foo{
静态constexpr float val{0.0f};
};
模板
constexpr float Foo::val;
但是由于
val
在类范围内被初始化,我不能为不同的
N
指定不同的
val

如果
val
不是
constexpr
而是
const
,则此操作有效:

//好的,但不是我想要的
模板
结构Foo{
静态常数浮点值;
};
模板
常量浮点Foo::val=3.14f;
模板
常量浮点Foo::val=0.1f;
但是我不能使用
constexpr float val=Foo::val
,因为
Foo::val
不是常量表达式

因此,我想要实现的目标如下:

//我想要的东西,但是错误
模板
结构Foo{
静态constexpr float val;
};
模板
constexpr float Foo::val=3.14f;
模板
constexpr float Foo::val=0.1f;
但编译器抱怨:

错误:constexpr静态数据成员“val”的声明需要初始值设定项

如果我为
val
static constexpr float val{0.0f};
)添加一个初始值设定项,编译器会说:

错误:“Foo::val”的初始化重复
错误:“Foo::val”的初始化重复

多么讽刺:D

我知道的一个解决方法是使用(C++14):

//好的
结构Foo{
模板
静态constexpr float val{0.0f};
};
模板
constexpr float Foo::val=3.14f;
模板
constexpr float Foo::val=0.1f;
就目前而言,这是可以预期的。但是如果
Foo
中的其他成员(变量或函数)仍然需要模板参数(即
Foo
需要是类模板),则此解决方案不适用


你知道吗?C++ 20以下的C++解决方案是首选(C++ 20对我的项目来说太新了)。
template <int N>
struct Foo {
    static constexpr float val { 0.0f };
};
template <>
struct Foo<0> {
    static constexpr float val { 3.14f };
};
template <>
struct Foo<1> {
    static constexpr float val { 0.1f };
};
模板
结构Foo{
静态constexpr float val{0.0f};
};
模板
结构Foo{
静态constexpr float val{3.14f};
};
模板
结构Foo{
静态constexpr float val{0.1f};
};
或者为初始化创建一个函数助手

template <int N>
struct Foo {    
    static constexpr float get_val() {
        if constexpr (N == 0) return 3.14f;
        else if constexpr (N == 1) return 0.1f;
        else return 0.0f;
    }
    static constexpr float val { get_val() };
};
模板
结构Foo{
静态constexpr float get_val(){
如果constexpr(N==0)返回3.14f;
否则,如果constexpr(N==1)返回0.1f;
否则返回0.0f;
}
静态constexpr float val{get_val()};
};