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