I know that I can partially specialize class templates, and I know that I cannot partially specify function templates.
What about variable templates? I can't find documentation on whether they can be partially specialized.
And since the specialization still has a template parameter, it is called a partial specialization. Partial specialization also works for variable templates: But C++ forbids partial specialization on anything else than classes (or structs) and variables.
The template parameter list and the template argument list of a member of a partial specialization must match the parameter list and the argument list of the partial specialization. Just like with members of primary templates, they only need to be defined if used in the program.
In the above code, is_pointer has a primary template (the first struct) and a specialization (the second one). And since the specialization still has a template parameter, it is called a partial specialization. Partial specialization also works for variable templates:
When a class or variable (since C++14) template is instantiated, and there are partial specializations available, the compiler has to decide if the primary template is going to be used or one of its partial specializations. 1) If only one specialization matches the template arguments, that specialization is used.
Yes, according to [temp.arg.template]/2:
Any partial specializations associated with the primary class template or primary variable template are considered when a specialization based on the template template-parameter is instantiated. ...
And to [temp.expl.spec]/7:
... the placement of partial specialization declarations of class templates, variable templates, member class templates of non-template classes, static data member templates of non-template classes, member class templates of class templates, etc. ...
It also mentioned in [constraints.namespace.std]/3:
The behavior of a C++ program is undefined if it declares an explicit or partial specialization of any standard library variable template, except where explicitly permitted by the specification of that variable template.
Not to mention that all major compilers (Clang, GCC and MSVC) have no problems with them:
template <int x, int y>
constexpr int foo = -1;
template <>
constexpr float foo<1, 0> = 1.0;
template <int x>
constexpr double foo<1, x> = 1.1;
int main()
{
static_assert(foo<0, 0> == -1, "");
static_assert(foo<0, 1> == -1, "");
static_assert(foo<1, 0> == 1.0, "");
static_assert(foo<1, 1> == 1.1, "");
}
https://godbolt.org/z/R1c1zo
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