Reputation: 4902
I'm attempting to get access to a constexpr variable at compile time within a CRTP class. Below is a MVCE of this.
template <class T>
struct CRTP {
static constexpr int get_value() {
return T::value ;
}
static constexpr int crtp_value = get_value();
};
struct Derived: CRTP<Derived> {
static constexpr int value = 2;
};
int main() {
static_assert(Derived::crtp_value == 2, "Should result in 2");
return 0;
}
I can't however run this on MSVC. Am I doing something I shouldn't be doing here? This works in other compilers, see godbolt links:
MSVC claims:
example.cpp
<source>(3): error C2039: 'value': is not a member of 'Derived'
<source>(7): note: see declaration of 'Derived'
<source>(3): note: the template instantiation context (the oldest one first) is
<source>(7): note: see reference to class template instantiation 'CRTP<Derived>' being compiled
<source>(3): note: while compiling class template member function 'int CRTP<Derived>::get_value(void)'
<source>(3): error C2065: 'value': undeclared identifier
<source>(4): error C3615: constexpr function 'CRTP<Derived>::get_value' cannot result in a constant expression
<source>(3): note: failure was caused by control reaching the end of a constexpr function
<source>(12): error C2131: expression did not evaluate to a constant
<source>(12): note: failure was caused by a read of an uninitialized symbol
<source>(12): note: see usage of 'crtp_value'
Compiler returned: 2
which I cannot make heads or tails of.
How do I get accessing static constexpr member variables or member functions from the derived class in CRTP to work in MSVC?
Upvotes: 3
Views: 132
Reputation: 25408
This seems to work:
template <class T>
struct CRTP {
static const int crtp_value;
};
template <class T> const int CRTP <T>::crtp_value = T::value;
struct Derived : CRTP <Derived> {
static constexpr int value = 2;
};
int main() {
static_assert(Derived::value == 2, "Should result in 2");
}
Shouldn't be necessary, but hey.
Upvotes: 1