Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matching of class template partial specializations

N4527 14.5.5.1[temp.class.spec.match]

2 A partial specialization matches a given actual template argument list if the template arguments of the partial specialization can be deduced from the actual template argument list.

template<class T1, class T2, int I> class A             { }; // #1
template<class T, int I>            class A<T, T*, I>   { }; // #2
template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3
template<class T>                   class A<int, T*, 5> { }; // #4
template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5

A<int, int, 1>   a1; // uses #1
A<int, int*, 1>  a2; // uses #2, T is int, I is 1
A<int, char*, 5> a3; // uses #4, T is char
A<int, char*, 1> a4; // uses #5, T1 is int, T2 is char, I is 1
A<int*, int*, 2> a5; // ambiguous: matches #3 and #5

3 A non-type template argument can also be deduced from the value of an actual template argument of a non-type parameter of the primary template. [ Example: the declaration of a2 above. —end example ]

4 In a type name that refers to a class template specialization, (e.g., A<int, int, 1>) the argument list shall match the template parameter list of the primary template. The template arguments of a specialization are deduced from the arguments of the primary template.

In rule3, the example shows I is deduced from the third actual template argument 1, this is what the rule2 says. So as the second sentence of rule4, I think it is repeating what rule2 says.

What are the differences between them(rule2, rule3 and rule4)?

Another words, we already have rule2, what are the intents(meaning) of rule3 and the second sentence of rule4, why they are here?

like image 523
stackcpp Avatar asked Aug 31 '15 21:08

stackcpp


People also ask

Can you partially specialize a C++ function template?

You can choose to specialize only some of the parameters of a class template. This is known as partial specialization. Note that function templates cannot be partially specialized; use overloading to achieve the same effect.

What is a template partial?

Template partials are small bits of reusable template or tag parts. You could create a Template partial for any number of purposes, anywhere that you need to reuse a small portion of a template, including partial or complete tags, other variables, etc.

What is mean by template specialization?

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.

Is specialization of template C++?

It is possible in C++ to get a special behavior for a particular data type. This is called template specialization. Template allows us to define generic classes and generic functions and thus provide support for generic programming.


2 Answers

I think, the rule [temp.class.spec.match] 14.5.5.1\2 may be rewritten like this without changing its purport:

[temp.class.spec.match] 14.5.5.1\2 (modified)

A partial specialization matches a given actual template argument list if the template arguments of the partial specialization can be deduced from the actual template argument list according to 14.8.2.5, where P is the argument list of the partial specialization from its simple-template-id and A is the actual template argument list.

The rule [temp.deduct.type] 14.8.2.5\1 defines the process for deducing from types (I am not sure about templates though) only, so there is a need for the rule [temp.class.spec.match] 14.5.5.1\3, which adds to 14.5.5.1\2 cases with non-type template parameters of the primary template, which are not (partially) specialized in the partial specialization.

The rule [temp.class.spec.match] 14.5.5.1\4, as you noted in the comments above (1, 2), is just the clarification, that template arguments in the template-id corresponds to template parameters of the primary template, not its partial specializations, which may have different template-parameter-list s. Moreover, the second sentence of the rule most likely claims that the implicit template argument list of the primary template (14.5.5\4) is deduced (!) according to [temp.deduct.type] 14.8.2.5\9 from the actual argument list. So the phrases "implicit template argument list of the primary template" and "the template arguments of a specialization" imply one selfsame thing, and the phrases "the arguments of the primary template" and "the actual template argument list" imply another selfsame thing... But it also may be that authors intended to write this:

[temp.class.spec.match] 14.5.5.1\4 (modified)

In a type name that refers to a class template specialization the argument list shall match the template parameter list of the primary template. The template arguments of a partial specialization are deduced from the arguments of the primary template.

Whatever...

like image 135
Eugene Zavidovsky Avatar answered Sep 27 '22 18:09

Eugene Zavidovsky


The differences between rule two and rule four is the second and third template parameter. In example three:

A<int, char*, 5> a3; // uses #4, T is char

It uses rule4 because the third parameter clearly specializes to a const int 5, and the second parameter is specialized to accept a pointer type; its a unique specialization of class A.

I look at each specialization as a specific species of the class, and each specie has a unique signature (similar to overloading functions). The compiler is going to choose the specialization that matches the signature being used.

Rule three only makes sense without rule five, so after removing rule five, the intent of rule three would be to specialize any typenames of class A that: a) do not use a const int 5 for the third parameter b) do not use a pointer or as the second parameter c) do not use a `int` in the second parameter.

Since non of your examples use the unique signature of rule3, non of them use rule3 (given we remove the ambiguous rule5).

This could be better to understand if you only look at the template<...> scheme of the specialization, and not the signature <> of the specialization. The compiler is looking at the template scheme before looking at the specialization. Also, all other specializations of class A define the rules for any new specialization. To understand the intentions of a specialization, you have to understand the intentions of all the other specializations, and intention of a specialization is not defined by the standard, its defined by whoever implemented the specialization; ie. implementation details of the specialization truly define the intent.

like image 38
zackery.fix Avatar answered Sep 27 '22 17:09

zackery.fix