blob: c3f185b810a4b1ba2890fd0dfbaf7c290c6f779b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
#include <cstdlib>
/* Make sure `malloc' is linked into the program. If we don't, tests
in the accompanying expect file may fail:
evaluation of this expression requires the program to have a function
"malloc". */
void
dummy ()
{
void *p = malloc (16);
free (p);
}
/* 1. A standard conversion sequence is better than a user-defined sequence
which is better than an elipses conversion sequence. */
class A{};
class B: public A {public: operator int (){ return 1;}};
// standard vs user-defined
int foo0 (int) { return 10; }
int foo1 (int) { return 11; } // B -> int : user defined
int foo1 (A) { return 12; } // B -> A : standard
int test1 () {
B b;
return foo1(b); // 12
}
// user-defined vs ellipsis
int foo2 (int) { return 13;} // B -> int : user defined
int foo2 (...) { return 14;} // B -> ... : ellipsis
int test2(){
B b;
return foo2(b); // 13
}
/* 2. Standard Conversion sequence S1 is better than standard Conversion
S2 if: */
// - S1 has a better rank than S2
// see overload.exp for more comprehensive testing of this.
int foo3 (double) { return 21; } // float->double is 'promotion rank'
int foo3 (int) { return 22; } // float->int is 'conversion rank'
int test3(){
return foo3 (1.0f); // 21
}
// - S1 and S2 are both 'qualification conversions' but S1 cv-qualification
// is a subset of S2 cv-qualification.
int foo4 (const volatile int*) { return 23; }
int foo4 ( volatile int*) { return 24; }
int test4 () {
volatile int a = 5;
return foo4(&a); // 24
}
// - S1 and S2 have the same rank but:
// - S2 is a conversion of pointer or member-pointer to bool
int foo5 (bool) { return 25; }
int foo5 (void*) { return 26; }
int test5 () {
char *a;
return foo5(a); // 26
}
// - Class B publicly extends class A and S1 is a conversion of
// B* to A* and S2 is a conversion B* to void*
int foo6 (void*) { return 27; }
int foo6 (A*) { return 28; }
int test6 () {
B *bp;
return foo6(bp); // 28
}
// - Class C publicly extends Class B which publicly extends
// class A and S1 is a conversion of C* to B* and S2 is a
// conversion C* to A*.
class C: public B {};
int foo7 (A*) { return 29; }
int foo7 (B*) { return 210; }
int test7 () {
C *cp;
return foo7(cp); // 210
}
// - Same as above but for references.
int foo8 (A&) { return 211; }
int foo8 (B&) { return 212; }
int test8 () {
C c;
return foo8(c); // 212
}
// - Same as above but passing by copy.
int foo9 (A) { return 213; }
int foo9 (B) { return 214; }
int test9 () {
C c;
return foo9(c); // 212
}
// - S1 is a conversion of A::* to B::* and S2 is a conversion of
// A::* to C::8.
int foo10 (void (C::*)()) { return 215; }
int foo10 (void (B::*)()) { return 216; }
int test10 () {
void (A::*amp)();
return foo10(amp); // 216
}
// - S1 is a subsequence of S2
int foo101 (volatile const char*) { return 217; } // array-to-pointer conversion
// plus qualification conversion
int foo101 ( const char*) { return 218; } // array-to-pointer conversion
int test101 () {
return foo101("abc"); // 216
}
/* 3. User defined conversion U1 is better than user defined Conversion U2,
if U1 and U2 are using the same conversion function but U1 has a better
second standard conversion sequence than U2. */
class D {public: operator short(){ return 0;}};
int foo11 (float) { return 31; }
int foo11 (int) { return 32; }
int test11 () {
D d;
return foo11(d); // 32
}
/* 4. Function Level Ranking.
All else being equal some functions are preferred by overload resolution.
Function F1 is better than function F2 if: */
// - F1 is a non-template function and F2 is a template function
template<class T> int foo12(T) { return 41; }
int foo12(int) { return 42; }
int test12 (){
return foo12(1); //42
}
// - F1 is a more specialized template instance
template<class T> int foo13(T) { return 43; }
template<class T> int foo13(T*) { return 44; }
int test13 (){
char *c;
return foo13(c); // 44
}
// - The context is user defined conversion and F1 has
// a better return type than F2
class E {
public:
operator double () {return 45; }
operator int () {return 46; }
};
int foo14 (int a) {return a;}
int test14 (){
E e;
return foo14(e); // 46
}
/* Test cv qualifier overloads. */
int foo15 (char *arg) { return 47; }
int foo15 (const char *arg) { return 48; }
int foo15 (volatile char *arg) { return 49; }
int foo15 (const volatile char *arg) { return 50; }
static int
test15 ()
{
char *c = 0;
const char *cc = 0;
volatile char *vc = 0;
const volatile char *cvc = 0;
// 47 + 48 + 49 + 50 = 194
return foo15 (c) + foo15 (cc) + foo15 (vc) + foo15 (cvc);
}
int main() {
dummy ();
B b;
foo0(b);
foo1(b);
test1();
foo2(b);
test2();
foo3(1.0f);
test3();
volatile int a;
foo4(&a);
test4();
char *c;
foo5(c);
test5();
B *bp;
foo6(bp);
test6();
C *cp;
foo7(cp);
test7();
C co;
foo8(co);
test8();
foo9(co);
test9();
void (A::*amp)();
foo10(amp);
test10();
foo101("abc");
test101();
D d;
foo11(d);
test11();
foo12(1);
test12();
foo13(c);
test13();
E e;
foo14(e);
test14();
const char *cc = 0;
volatile char *vc = 0;
const volatile char *cvc = 0;
test15 ();
return 0; // end of main
}
|