According to C++1y/C++14 N3690, does the type of a variable template specialization have to be the same as the type of the primary template?
template<int x>
char y = f(x);
template<>
double y<42> = g();
And if so, is it possible to leave the primary undefined somehow?
template<int x>
???? y = ???; // undefined
template<>
double y<42> = g();
Where is this covered in the draft?
The equivalent functionality for a class template would be:
template<int x>
struct S
{
static char y;
};
template<>
struct S<42>
{
static double y;
};
and
template<int x>
struct S; // undefined
template<>
struct S<42>
{
static double y;
};
It's a bit risky to extrapolate that Clang is expressing the feature intended for standardization. (NB: I didn't refer to anything for this answer.)
Of course the fallout from allowing a change of type is that you can't specialize the template after it's been referenced in any way, whereas for all other kinds of templates the cutoff time is at ODR-use. Unless they're planning something wacky, this looks like a Clang bug.
You can always use a type template to declare the type of the variable template.
Now
x_type
may be specialized. This just guards against the possibility that Clang is currently buggy. It doesn't allow you to refer to an object of indeterminate type. C++ just doesn't support that. Referring to the object ODR-uses the class template specialization.Does the type of a variable template specialization have to be the same as the type of the primary template?
No, an explicit (or partial) specialization of a variable template can specify a type different from the type that would be implied by an implicit instantiation. When implementing the feature for Clang, we discovered that the specification had no rule requiring the type to match in this case, and we brought the issue to the C++ core working group, where it was confirmed that this omission was intentional.
Is it possible to leave the primary undefined somehow?
It is not possible to declare the primary variable template without specifying at type -- there is no syntax that would allow such a thing.
Where is this covered in the draft?
Both of these are covered by omission -- there is no rule requiring the types to match, and there is no syntax for declaring a variable template without a type. So I can't point you at any particular part of the standard and say "here's where the rule isn't".
If you have access to the C++ standard committee's reflectors, see the thread starting with core-23901 for the discussion of this.
The following compiles with clang trunk
-std=c++1y
:So either a specialization of a variable template doesn't need to have the same type as its primary, or clang has a buggy implementation of N3690
I would fully expect that the declaration of a specialization needs to match the primary template exactly, including its type. This isn't anything new for variable templates. I haven't chased down the details in the standard, yet, to see where it specifies this detail.
The code below seems to do something akin to what you want, i.e., leave the variable type sort of open: