I tried to forward-declare a constexpr
variable template like this:
template<typename>
constexpr std::size_t iterator_category_value;
The goal was to document that every specialization should be constexpr
but I have to admit that I never checked whether it was legal or not and g++ was happy with it. However, when I tried to compile this spinnet with clang++ instead, I got the following error:
error: default initialization of an object of const type 'const std::size_t' (aka 'const unsigned long') constexpr std::size_t iterator_category_value; ^ = 0
The error makes sense, and removing constexpr
makes it disappear, so that's not a real problem. However, I am curious now: does the standard allow such a constexpr
forward declaration for a variable template or is it illegal? g++ and clang++ seem to disagree and I would like to know where I should submit a bug report if needed.
Both of them complain for a forward-declared constepxr
variable which is not a variable template, so the variable template context seems to be what makes the compilers disagree.
In the C++14 standard, it seems pretty clear that initialization is required. From section 7.5.1 paragraph 9,
As for the exact meaning of "object declaration", Section 7 paragraph 7 states:
Clang is correct. The declaration of a variable template is an object declaration ([dcl.dcl]/9), hence it must provide an initializer as per [dcl.constexpr]/9:
There is effectively no way of "forward" declaring an object as
constexpr
in the first place, though; Ifconstexpr
is applied to the declaration of a variable, it shall be a definition ([dcl.constexpr]/1).