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 } 208