简体   繁体   English

初始化 class 模板的 static constexpr 成员变量

[英]Initialize static constexpr member variable of class template

Here is the situation: A class Foo with a template param int N has a static member variable float val .情况如下:具有模板参数int N的 class Foo具有 static 成员变量float val The value of val is corresponding to N and never changes, so I expect it to be constexpr . val的值对应于N并且永远不会改变,所以我希望它是constexpr

I know the common way of initializing static constexpr member variable is:我知道初始化 static constexpr 成员变量的常用方法是:

// ok, but not what I want
template <int N>
struct Foo {
    static constexpr float val { 0.0f };
};
template <int N>
constexpr float Foo<N>::val;

But because val is initialized inside the class scope, I cannot specify different val for different N .但是因为val是在 class scope内部初始化的,所以我不能为不同的N指定不同的val

If val is not constexpr but const , this works:如果val不是constexpr而是const ,则有效:

// ok, but not what I want
template <int N>
struct Foo {
    static const float val;
};
template <>
const float Foo<0>::val = 3.14f;
template <>
const float Foo<1>::val = 0.1f;

But then I can't use constexpr float val = Foo<0>::val;但是我不能使用constexpr float val = Foo<0>::val; , because Foo<0>::val is not a constant expression. ,因为Foo<0>::val不是常量表达式。

So, the goal I want to achieve is something like below:所以,我想要实现的目标如下:

// the thing I want, but error
template <int N>
struct Foo {
    static constexpr float val;
};
template <>
constexpr float Foo<0>::val = 3.14f;
template <>
constexpr float Foo<1>::val = 0.1f;

But the compiler complains:但是编译器抱怨:

error: declaration of constexpr static data member 'val' requires an initializer错误:constexpr static 数据成员“val”的声明需要初始化程序

And if I add an initializer for val ( static constexpr float val { 0.0f }; ), the compiler says:如果我为val添加一个初始化程序( static constexpr float val { 0.0f }; ),编译器会说:

error: duplicate initialization of 'Foo<0>::val'错误:'Foo<0>::val' 的重复初始化
error: duplicate initialization of 'Foo<1>::val'错误:'Foo<1>::val' 的重复初始化

How ironic:D多么讽刺:D

A workaround I know is using variable template (C++14):我知道的一种解决方法是使用变量模板(C++14):

// ok
struct Foo {
    template <int N>
    static constexpr float val { 0.0f };
};
template <>
constexpr float Foo::val<0> = 3.14f;
template <>
constexpr float Foo::val<1> = 0.1f;

This works as expected, for now.目前,这按预期工作。 But if other members (variables or functions) in Foo still need the template param (ie Foo need to be class template), this solution is not applicable.但如果Foo中的其他成员(变量或函数)仍然需要模板参数(即Foo需要为 class 模板),则此方案不适用。

Any idea about this?对此有任何想法吗? Solutions using C++ standard below C++20 are preferred (C++20 is just too new for my project).首选使用低于 C++20 的 C++ 标准的解决方案(C++20 对我的项目来说太新了)。

You can specialize the class template as您可以将 class 模板专门化为

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 };
};

Or make a function helper for initialization.或者制作一个 function 帮助器进行初始化。

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() };
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM