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