Derived is incomplete at the point at which the Base<Derived> is created ([class.mem] / 2), which happens right during the definition. You used constexpr , which requires an initializer in accordance with [class.static.data] / 3, and when creating Base<Derived> its static data members ([temp.inst] / 3), which include initializers, are also declared. However, initializers try to create an object of an incomplete type that is poorly formed.
Instead, you can declare your member as const :
template<class T> class Base { public: static const T a; }; template <typename T> constexpr T Base<T>::a = T(1);
since the initializer is now in the definition, an instance of this initializer can be delayed until, for example, Derived completed. Demo using Clang.
Note that Clang does not yet consider a as constexpr , because it cannot program its definition. See Bug # 24541 .
source share