Can alias templates (14.5.7) be explicitly specialised (14.7.3)?
My standard-fu fails me, and I can't find a compiler to test on.
The text "when a template-id refers to the specialization of an alias template" implies yes, but then the example appears to refer to something else, implying no.
NB. I'm working from n3242, one behind the FDIS, in which the title of this section is "Aliase templates". Lol.
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
Alias templates are a way to give a name to a family of types. Template parameters can be types, non-types, and templates themselves.
You can use an alias declaration to declare a name to use as a synonym for a previously declared type. (This mechanism is also referred to informally as a type alias). You can also use this mechanism to create an alias template, which can be useful for custom allocators.
Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.
What the Standard means by "specialization" is the transformation of a generic template to a more specialized entity. For example, instantiating a non-member class template yields a class that's not a template anymore. The term "specialization" is two fold, and can refer to a generated specialization (which is a specialization that was instantiated, possibly from a partial specialization) and to an explicit specialization (which is what you referred to).
Alias templates aren't instantiated and there aren't specializations of them. There is nothing they could instantiate to. Instead, whenever their name is followed by a template argument list, the type denoted is the type you get by replacing the name and argument list by the alias'ed type, replacing all template parameter references with the arguments given in the argument list. That is, rather than the specialization of it being an alias, the alias template itself serves as an alias, without the need to instantiate anything. This replacement is done very early. Consider:
template<typename T> using ref = T&; template<typename T> void f(ref<T> x) { x = 10; } int main() { int a; f(a); return a; /* 10 */ }
The replacement is done at the time ref<T>
is named (such a names are used to refer to class or function template specializations; hence the spec describes such names to "refer to the specialization of an alias template"). That is, the parameter of f
has type T&
, and thus, T
can be deduced. This property is preventing explicit or partial specializations of alias templates. Because in order to pick the correct specialization of ref
, it needs to know T
. But to know it, it needs to compare ref<T>
against the argument type to deduce T
. It's summarized in the paper N1406, "Proposed addition to C++: Typedef Templates", section 2.2
2.2 The Main Choice: Specialization vs. Everything Else
After discussion on the reflectors and in the Evolution WG, it turns out that we have to choose between two mutually exclusive models:
A typedef template is not itself an alias; only the (possibly-specialized) instantiations of the typedef template are aliases. This choice allows us to have specialization of typedef templates.
A typedef template is itself an alias; it cannot be specialized. This choice would allow:
- deduction on typedef template function parameters (see 2.4)
- a declaration expressed using typedef templates be the same as the declaration without typedef templates (see 2.5)
- typedef templates to match template template parameters (see 2.6)
It should be noted that the quoted paper, which favors option 1, did not make it into C++0x.
EDIT: Because you desperately want to have a spec quote saying so explicitly. 14.5p3 is one that does
Because an alias-declaration cannot declare a template-id, it is not possible to partially or explicitly specialize an alias template.
Bjarne says:
Specialization works (you can alias a set of specializations but you cannot specialize an alias)
And, whilst not an explicit rule, "alias templates" are missing from the following list at 14.7.3/1:
An explicit specialization of any of the following:
- function template
- class template
- member function of a class template
- static data member of a class template
- member class of a class template
- member class template of a class or class template
- member function template of a class or class template
can be declared[...]
I think that this is the best guarantee you'll get.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With