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
|
/* 1. A standard covnersion 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 squence 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 memeber-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
}
int main() {
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();
return 0; // end of main
}
|