(A toy, minimal not-working example)
The next code won't compile with cpp20/17:
template<typename TSomeTemplate>
struct A
{
static constexpr size_t B = 1;
template<typename T, typename... Ts>
static constexpr size_t C = 4;
template<typename T>
static constexpr size_t C<T> = B;
};
int main()
{
A<int>::C<int>;
return 0;
}
With the error of "Expression did not evaluate to constant" regarding the last line in the struct. However, it does compile with full specialization, or without referencing B:
template<typename TSomeTemplate>
struct Works
{
static constexpr size_t B = 1;
template<typename T, typename... Ts>
static constexpr size_t C = 4;
template<>
static constexpr size_t C<int> = B;
};
template<typename TSomeTemplate>
struct AlsoWorks
{
static constexpr size_t B = 1;
template<typename T, typename... Ts>
static constexpr size_t C = 4;
template<typename T>
static constexpr size_t C<T> = 2;
};
Why is it so? How can I make the first struct work?
GCC and MSVC are wrong in rejecting the code as the program is well-formed.
B
is a constant expression and can be used as an initializer when initializing C
during its partial specialization. This is a msvc bug reported here as:
MSVC rejects valid code when using constexpr static data member as initializer.
Moreover, we are allowed to provide a partial specialization for C
(as you did). This is a gcc bug reported as:
GCC rejects valid code involving partial specialization of variable template.