tmp/tmps6mcdyve/{from.md → to.md}
RENAMED
|
@@ -27,20 +27,29 @@ specialized template is the one chosen by the partial ordering process.
|
|
| 27 |
|
| 28 |
To produce the transformed template, for each type, non-type, or
|
| 29 |
template template parameter (including template parameter packs (
|
| 30 |
[[temp.variadic]]) thereof) synthesize a unique type, value, or class
|
| 31 |
template respectively and substitute it for each occurrence of that
|
| 32 |
-
parameter in the function type of the template.
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
of
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
``` cpp
|
| 44 |
struct A { };
|
| 45 |
template<class T> struct B {
|
| 46 |
template<class R> int operator*(R&); // #1
|
|
@@ -56,14 +65,18 @@ int main() {
|
|
| 56 |
B<A> b;
|
| 57 |
b * a; // calls #1a
|
| 58 |
}
|
| 59 |
```
|
| 60 |
|
|
|
|
|
|
|
| 61 |
Using the transformed function template’s function type, perform type
|
| 62 |
deduction against the other template as described in
|
| 63 |
[[temp.deduct.partial]].
|
| 64 |
|
|
|
|
|
|
|
| 65 |
``` cpp
|
| 66 |
template<class T> struct A { A(); };
|
| 67 |
|
| 68 |
template<class T> void f(T);
|
| 69 |
template<class T> void f(T*);
|
|
@@ -77,23 +90,29 @@ template<class T> void h(A<T>&);
|
|
| 77 |
|
| 78 |
void m() {
|
| 79 |
const int* p;
|
| 80 |
f(p); // f(const T*) is more specialized than f(T) or f(T*)
|
| 81 |
float x;
|
| 82 |
-
g(x); //
|
| 83 |
A<int> z;
|
| 84 |
h(z); // overload resolution selects h(A<T>&)
|
| 85 |
const A<int> z2;
|
| 86 |
h(z2); // h(const T&) is called because h(A<T>&) is not callable
|
| 87 |
}
|
| 88 |
```
|
| 89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
Since partial ordering in a call context considers only parameters for
|
| 91 |
which there are explicit call arguments, some parameters are ignored
|
| 92 |
(namely, function parameter packs, parameters with default arguments,
|
| 93 |
and ellipsis parameters).
|
| 94 |
|
|
|
|
|
|
|
| 95 |
``` cpp
|
| 96 |
template<class T> void f(T); // #1
|
| 97 |
template<class T> void f(T*, int=1); // #2
|
| 98 |
template<class T> void g(T); // #3
|
| 99 |
template<class T> void g(T*, ...); // #4
|
|
@@ -105,10 +124,14 @@ int main() {
|
|
| 105 |
f(ip); // calls #2
|
| 106 |
g(ip); // calls #4
|
| 107 |
}
|
| 108 |
```
|
| 109 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
``` cpp
|
| 111 |
template<class T, class U> struct A { };
|
| 112 |
|
| 113 |
template<class T, class U> void f(U, A<U, T>* p = 0); // #1
|
| 114 |
template< class U> void f(U, A<U, U>* p = 0); // #2
|
|
@@ -120,10 +143,14 @@ void h() {
|
|
| 120 |
f<int>(42); // error: ambiguous
|
| 121 |
g(42); // error: ambiguous
|
| 122 |
}
|
| 123 |
```
|
| 124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
``` cpp
|
| 126 |
template<class T, class... U> void f(T, U...); // #1
|
| 127 |
template<class T > void f(T); // #2
|
| 128 |
template<class T, class... U> void g(T*, U...); // #3
|
| 129 |
template<class T > void g(T); // #4
|
|
@@ -132,5 +159,9 @@ void h(int i) {
|
|
| 132 |
f(&i); // error: ambiguous
|
| 133 |
g(&i); // OK: calls #3
|
| 134 |
}
|
| 135 |
```
|
| 136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
To produce the transformed template, for each type, non-type, or
|
| 29 |
template template parameter (including template parameter packs (
|
| 30 |
[[temp.variadic]]) thereof) synthesize a unique type, value, or class
|
| 31 |
template respectively and substitute it for each occurrence of that
|
| 32 |
+
parameter in the function type of the template.
|
| 33 |
+
|
| 34 |
+
[*Note 1*: The type replacing the placeholder in the type of the value
|
| 35 |
+
synthesized for a non-type template parameter is also a unique
|
| 36 |
+
synthesized type. — *end note*]
|
| 37 |
+
|
| 38 |
+
If only one of the function templates *M* is a non-static member of some
|
| 39 |
+
class *A*, *M* is considered to have a new first parameter inserted in
|
| 40 |
+
its function parameter list. Given cv as the cv-qualifiers of *M* (if
|
| 41 |
+
any), the new parameter is of type “rvalue reference to cv *A*” if the
|
| 42 |
+
optional *ref-qualifier* of *M* is `&&` or if *M* has no *ref-qualifier*
|
| 43 |
+
and the first parameter of the other template has rvalue reference type.
|
| 44 |
+
Otherwise, the new parameter is of type “lvalue reference to cv *A*”.
|
| 45 |
+
|
| 46 |
+
[*Note 2*: This allows a non-static member to be ordered with respect
|
| 47 |
+
to a non-member function and for the results to be equivalent to the
|
| 48 |
+
ordering of two equivalent non-members. — *end note*]
|
| 49 |
+
|
| 50 |
+
[*Example 1*:
|
| 51 |
|
| 52 |
``` cpp
|
| 53 |
struct A { };
|
| 54 |
template<class T> struct B {
|
| 55 |
template<class R> int operator*(R&); // #1
|
|
|
|
| 65 |
B<A> b;
|
| 66 |
b * a; // calls #1a
|
| 67 |
}
|
| 68 |
```
|
| 69 |
|
| 70 |
+
— *end example*]
|
| 71 |
+
|
| 72 |
Using the transformed function template’s function type, perform type
|
| 73 |
deduction against the other template as described in
|
| 74 |
[[temp.deduct.partial]].
|
| 75 |
|
| 76 |
+
[*Example 2*:
|
| 77 |
+
|
| 78 |
``` cpp
|
| 79 |
template<class T> struct A { A(); };
|
| 80 |
|
| 81 |
template<class T> void f(T);
|
| 82 |
template<class T> void f(T*);
|
|
|
|
| 90 |
|
| 91 |
void m() {
|
| 92 |
const int* p;
|
| 93 |
f(p); // f(const T*) is more specialized than f(T) or f(T*)
|
| 94 |
float x;
|
| 95 |
+
g(x); // ambiguous: g(T) or g(T&)
|
| 96 |
A<int> z;
|
| 97 |
h(z); // overload resolution selects h(A<T>&)
|
| 98 |
const A<int> z2;
|
| 99 |
h(z2); // h(const T&) is called because h(A<T>&) is not callable
|
| 100 |
}
|
| 101 |
```
|
| 102 |
|
| 103 |
+
— *end example*]
|
| 104 |
+
|
| 105 |
+
[*Note 3*:
|
| 106 |
+
|
| 107 |
Since partial ordering in a call context considers only parameters for
|
| 108 |
which there are explicit call arguments, some parameters are ignored
|
| 109 |
(namely, function parameter packs, parameters with default arguments,
|
| 110 |
and ellipsis parameters).
|
| 111 |
|
| 112 |
+
[*Example 3*:
|
| 113 |
+
|
| 114 |
``` cpp
|
| 115 |
template<class T> void f(T); // #1
|
| 116 |
template<class T> void f(T*, int=1); // #2
|
| 117 |
template<class T> void g(T); // #3
|
| 118 |
template<class T> void g(T*, ...); // #4
|
|
|
|
| 124 |
f(ip); // calls #2
|
| 125 |
g(ip); // calls #4
|
| 126 |
}
|
| 127 |
```
|
| 128 |
|
| 129 |
+
— *end example*]
|
| 130 |
+
|
| 131 |
+
[*Example 4*:
|
| 132 |
+
|
| 133 |
``` cpp
|
| 134 |
template<class T, class U> struct A { };
|
| 135 |
|
| 136 |
template<class T, class U> void f(U, A<U, T>* p = 0); // #1
|
| 137 |
template< class U> void f(U, A<U, U>* p = 0); // #2
|
|
|
|
| 143 |
f<int>(42); // error: ambiguous
|
| 144 |
g(42); // error: ambiguous
|
| 145 |
}
|
| 146 |
```
|
| 147 |
|
| 148 |
+
— *end example*]
|
| 149 |
+
|
| 150 |
+
[*Example 5*:
|
| 151 |
+
|
| 152 |
``` cpp
|
| 153 |
template<class T, class... U> void f(T, U...); // #1
|
| 154 |
template<class T > void f(T); // #2
|
| 155 |
template<class T, class... U> void g(T*, U...); // #3
|
| 156 |
template<class T > void g(T); // #4
|
|
|
|
| 159 |
f(&i); // error: ambiguous
|
| 160 |
g(&i); // OK: calls #3
|
| 161 |
}
|
| 162 |
```
|
| 163 |
|
| 164 |
+
— *end example*]
|
| 165 |
+
|
| 166 |
+
— *end note*]
|
| 167 |
+
|