Here is the situation: A class Foo with a template param int N has a static member variable float val. The value of val is corresponding to N and never changes, so I expect it to be constexpr.
I know the common way of initializing static constexpr member variable is:
// 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.
If val is not constexpr but const, this works:
// 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;, because Foo<0>::val is not a constant expression.
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
And if I add an initializer for val (static constexpr float val { 0.0f };), the compiler says:
error: duplicate initialization of 'Foo<0>::val'
error: duplicate initialization of 'Foo<1>::val'
How ironic :D
A workaround I know is using variable template (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 (i.e. Foo need to be class template), this solution is not applicable.
Any idea about this? Solutions using C++ standard below C++20 are preferred (C++20 is just too new for my project).