Files
2025-10-25 03:02:53 +03:00

254 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[temp.func.order]
# 13 Templates [[temp]](./#temp)
## 13.7 Template declarations [[temp.decls]](temp.decls#temp.func.order)
### 13.7.7 Function templates [[temp.fct]](temp.fct#temp.func.order)
#### 13.7.7.3 Partial ordering of function templates [temp.func.order]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4312)
If multiple function templates share a name,
the use of that name can be ambiguous because
template argument deduction ([[temp.deduct]](temp.deduct "13.10.3Template argument deduction")) may identify
a specialization for more than one function template[.](#1.sentence-1)
[*Partial ordering*](#def:template,function,partial_ordering "13.7.7.3Partial ordering of function templates[temp.func.order]") 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)](#1.1)
during overload resolution for a call to a function template specialization ([[over.match.best]](over.match.best "12.2.4Best viable function"));
- [(1.2)](#1.2)
when the address of a function template specialization is taken;
- [(1.3)](#1.3)
when a placement operator delete that is a
function template
specialization
is selected to match a placement operator new ([[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation "6.8.6.5.3Deallocation functions"), [[expr.new]](expr.new "7.6.2.8New"));
- [(1.4)](#1.4)
when a [friend function declaration](temp.friend "13.7.5Friends[temp.friend]"), an[explicit instantiation](temp.explicit "13.9.3Explicit instantiation[temp.explicit]") or an [explicit specialization](temp.expl.spec "13.9.4Explicit specialization[temp.expl.spec]") refers to
a function template specialization[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4339)
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[.](#2.sentence-1)
The deduction process determines whether
one of the templates is more specialized than the other[.](#2.sentence-2)
If so, the
more specialized template is the one chosen by the partial ordering
process[.](#2.sentence-3)
If both deductions succeed, the partial ordering selects
the more constrained template (if one exists) as determined below[.](#2.sentence-4)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4351)
To produce the transformed template, for each
type, constant,
type template, variable template, or concept
template parameter (including template parameter packs ([[temp.variadic]](temp.variadic "13.7.4Variadic templates"))
thereof) synthesize a unique type, value, class template,
variable template, or concept,
respectively, and substitute it for each occurrence of that parameter
in the function type of the template[.](#3.sentence-1)
[*Note [1](#note-1)*:
The type replacing the placeholder
in the type of the value synthesized for a constant template parameter
is also a unique synthesized type[.](#3.sentence-2)
— *end note*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4369)
A synthesized template has the same [*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") as
its corresponding template template parameter[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4375)
Each function template M that is a member function
is considered to have
a new first parameter of type X(M), described below,
inserted in its function parameter list[.](#5.sentence-1)
If exactly one of the function templates was considered by overload resolution
via a rewritten candidate ([[over.match.oper]](over.match.oper "12.2.2.3Operators in expressions"))
with a reversed order of parameters,
then the order of the function parameters in its transformed template
is reversed[.](#5.sentence-2)
For a function template M with cv-qualifiers cv that is a member of a class A:
- [(5.1)](#5.1)
The type X(M) is “rvalue reference to cv A”
if the optional [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]") ofM is && or
if M has no [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1General[dcl.decl.general]") and
the positionally-corresponding parameter of the other transformed template
has rvalue reference type;
if this determination depends recursively upon
whether X(M) is an rvalue reference type,
it is not considered to have rvalue reference type[.](#5.1.sentence-1)
- [(5.2)](#5.2)
Otherwise, X(M) is “lvalue reference to cv A”[.](#5.2.sentence-1)
[*Note [2](#note-2)*:
This allows a non-static
member to be ordered with respect to a non-member function and for the results
to be equivalent to the ordering of two equivalent non-members[.](#5.sentence-4)
— *end note*]
[*Example [1](#example-1)*: struct A { };template<class T> struct B {template<class R> int operator*(R&); // #1};
template<class T, class R> int operator*(T&, R&); // #2// The declaration of B::operator* is transformed into the equivalent of// template<class R> int operator*(B<A>&, R&); // #1aint main() { A a;
B<A> b;
b * a; // calls #1} — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4428)
Using the transformed function template's function type,
perform type deduction against the other template as described in [[temp.deduct.partial]](temp.deduct.partial "13.10.3.5Deducing template arguments during partial ordering")[.](#6.sentence-1)
[*Example [2](#example-2)*: template<class T> struct A { A(); };
template<class T> void f(T);template<class T> void f(T*);template<class T> void f(const T*);
template<class T> void g(T);template<class T> void g(T&);
template<class T> void h(const T&);template<class T> void h(A<T>&);
void m() {const int* p;
f(p); // f(const T*) is more specialized than f(T) or f(T*)float x;
g(x); // ambiguous: g(T) or g(T&) A<int> z;
h(z); // overload resolution selects h(A<T>&)const A<int> z2;
h(z2); // h(const T&) is called because h(A<T>&) is not callable} — *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4459)
[*Note [3](#note-3)*:
Since, in a call context, such type deduction considers only parameters
for which there are explicit call arguments, some parameters are ignored (namely,
function parameter packs, parameters with default arguments, and ellipsis
parameters)[.](#7.sentence-1)
[*Example [3](#example-3)*: template<class T> void f(T); // #1template<class T> void f(T*, int=1); // #2template<class T> void g(T); // #3template<class T> void g(T*, ...); // #4int main() {int* ip;
f(ip); // calls #2 g(ip); // calls #4} — *end example*]
[*Example [4](#example-4)*: template<class T, class U> struct A { };
template<class T, class U> void f(U, A<U, T>* p = 0); // #1template< class U> void f(U, A<U, U>* p = 0); // #2template<class T > void g(T, T = T()); // #3template<class T, class... U> void g(T, U ...); // #4void h() { f<int>(42, (A<int, int>*)0); // calls #2 f<int>(42); // error: ambiguous g(42); // error: ambiguous} — *end example*]
[*Example [5](#example-5)*: template<class T, class... U> void f(T, U...); // #1template<class T > void f(T); // #2template<class T, class... U> void g(T*, U...); // #3template<class T > void g(T); // #4void h(int i) { f(&i); // OK, calls #2 g(&i); // OK, calls #3} — *end example*]
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4512)
If deduction against the other template succeeds for both transformed templates,
constraints can be considered as follows:
- [(8.1)](#8.1)
If their [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]")*s* (possibly including [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")*s* invented for an abbreviated function template ([[dcl.fct]](dcl.fct "9.3.4.6Functions"))) or
function parameter lists differ in length,
neither template is more specialized than the other[.](#8.1.sentence-1)
- [(8.2)](#8.2)
Otherwise:
* [(8.2.1)](#8.2.1)
If exactly one of the templates was considered by overload resolution
via a rewritten candidate with reversed order of parameters:
+
[(8.2.1.1)](#8.2.1.1)
If, for either template, some of the template parameters
are not deducible from their function parameters,
neither template is more specialized than the other.
+
[(8.2.1.2)](#8.2.1.2)
If there is either no reordering or more than one reordering
of the associated [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]") such that
- [(8.2.1.2.1)](#8.2.1.2.1)
the corresponding [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")*s* of the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]")*s* are equivalent and
- [(8.2.1.2.2)](#8.2.1.2.2)
the function parameters that positionally correspond
between the two templates are of the same type,
neither template is more specialized than the other.
* [(8.2.2)](#8.2.2)
Otherwise, if the corresponding [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")*s* of the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]")*s* are not equivalent ([[temp.over.link]](temp.over.link "13.7.7.2Function template overloading")) or
if the function parameters that positionally correspond
between the two templates are not of the same type,
neither template is more specialized than the other[.](#8.2.sentence-1)
- [(8.3)](#8.3)
Otherwise, if the context in which the partial ordering is done
is that of a call to a conversion function and
the return types of the templates are not the same,
then neither template is more specialized than the other[.](#8.3.sentence-1)
- [(8.4)](#8.4)
Otherwise,
if one template is more constrained than the other ([[temp.constr.order]](temp.constr.order "13.5.5Partial ordering by constraints")),
the more constrained template is more specialized than the other[.](#8.4.sentence-1)
- [(8.5)](#8.5)
Otherwise, neither template is more specialized than the other[.](#8.5.sentence-1)
[*Example [6](#example-6)*: template <typename> constexpr bool True = true;template <typename T> concept C = True<T>;
void f(C auto &, auto &) = delete;template <C Q> void f(Q &, C auto &);
void g(struct A *ap, struct B *bp) { f(*ap, *bp); // OK, can use different methods to produce template parameters}template <typename T, typename U> struct X {};
template <typename T, C U, typename V> bool operator==(X<T, U>, V) = delete;template <C T, C U, C V> bool operator==(T, X<U, V>);
void h() { X<void *, int>{} == 0; // OK, correspondence of [T, U, V] and [U, V, T]} — *end example*]