简体   繁体   中英

C++ wording for template explicit specialization

If we consider function template overloading, the standard behaviour in C++ is to first choose the "most specialized" overload (out of the base templates). The next step is to see if the chosen overload is explicitly specialized. If it is, the explicit specialization that matches will be chosen.

Could you point to the place in the standard that defines the second step (the highlighted part in the previous paragraph)?

Thank you.

From the working draft (N4713):

17.6.6.2 Partial ordering of function templates [temp.func.order]
1. If a function template is overloaded, the use of a function template specialization might be ambiguous because template argument deduction may associate the function template specialization with more than one function template declaration. Partial ordering of overloaded function template declarations is used in the following contexts to select the function template to which a function template specialization refers:
(1.1) — during overload resolution for a call to a function template specialization;
(1.2) — when the address of a function template specialization is taken;
(1.3) — when a placement operator delete that is a function template specialization is selected to match a placement operator new;
(1.4) — when a friend function declaration, an explicit instantiation or an explicit specialization refers to a function template specialization.

Also:

2 Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type. The deduction process determines whether one of the templates is more specialized than the other . If so, the more specialized template is the one chosen by the partial ordering process. If both deductions succeed, the partial ordering selects the more constrained template as described by the rules in 17.4.4.

17.6.5.2 Partial ordering of class template specializations [temp.class.order]
1 For two class template partial specializations, the first is more specialized than the second if, given the following rewrite to two function templates, the first function template is more specialized than the second according to the ordering rules for function templates (17.6.6.2): (1.1) — Each of the two function templates has the same template parameters and associated constraints (17.4.2) as the corresponding partial specialization.
(1.2) — Each function template has a single function parameter whose type is a class template specialization where the template arguments are the corresponding template parameters from the function template for each template argument in the template-argument-list of the simple-template-id of the partial specialization .
2 [ Example:

 template<int I, int J, class T> class X { }; template<int I, int J> class X<I, J, int> { }; // #1 template<int I> class X<I, I, int> { }; // #2 template<int I0, int J0> void f(X<I0, J0, int>); // A template<int I0> void f(X<I0, I0, int>); // B template <auto v> class Y { }; template <auto* p> class Y<p> { }; // #3 template <auto** pp> class Y<pp> { }; // #4 template <auto* p0> void g(Y<p0>); // C template <auto** pp0> void g(Y<pp0>); // D 

According to the ordering rules for function templates, the function template B is more specialized than the function template A and the function template D is more specialized than the function template C. Therefore, the partial specialization #2 is more specialized than the partial specialization #1 and the partial specialization #4 is more specialized than the partial specialization #3. —end example ]

[ Example:

 template<typename T> concept C = requires (T t) { tf(); }; template<typename T> concept D = C<T> && requires (T t) { tf(); }; template<typename T> class S { }; template<C T> class S<T> { }; // #1 template<D T> class S<T> { }; // #2 template<C T> void f(S<T>); // A template<D T> void f(S<T>); // B 

The partial specialization #2 is more specialized than #1 because B is more specialized than A . —end example ]

If I understand you correctly then perhaps you were referring to this from [temp.inst§4] :

Unless a function template specialization has been explicitly instantiated or explicitly specialized, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist or if the existence of the definition affects the semantics of the program [...]

Which, by way of negation, says that the explicit specialization gets the precedence.

The standard does not define formally what an explicit specialization is. The most relevant part I can find is the example in [temp.expl.spec]/1:

[ Example:

 template<class T> class stream; template<> class stream<char> { /* ... */ }; template<class T> class Array { /* ... */ }; template<class T> void sort(Array<T>& v) { /* ... */ } template<> void sort<char*>(Array<char*>&); 

Given these declarations, stream<char> will be used as the definition of streams of char s; other streams will be handled by class template specializations instantiated from the class template. Similarly, sort<char*> will be used as the sort function for arguments of type Array<char*> ; other Array types will be sorted by functions generated from the template. — end example ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM