类型转换:
// 类型转换测试
class SmallInt {
friend SmallInt operator+(const SmallInt &lhs, const SmallInt &rhs);
public:
SmallInt(int i = 0) : val(i) {}
explicit operator bool() { return bool(val); }
operator int() const { return val; }
operator const int() { return val; }
private:
int val;
};
SmallInt operator+(const SmallInt &lhs, const SmallInt &rhs) {
return SmallInt(int(lhs) + int(rhs));
}
测试代码:
void TypeConvertTest() {
SmallInt si1;
si1 = 4; // 4先转换为SmallInt(4),再执行赋值操作
si1 = 5.1; // 隐式的用户定位类型转换可以置于一个标准(内置)类型转换之前或者之后, 5.1 -> 5
// auto sum = si1 + 3; // si1转换为int值4,再执行4 + 3,在定义operator+(const SmallInt& lhs, const SmallInt& rhs)后存在二义性
// sum = si1 + 4.13; // 4.13 -> 4,在定义operator+(const SmallInt& lhs, const SmallInt& rhs)后存在二义性
if (si1) {
// 向bool的转换通常用在条件部分,因此一般定位为expicit,在条件部分会自动执行隐式转换
cout << "this is true" << endl;
}
int i = si1; // operator const int()
const int ci = si1; // operator const int()
return;
}
二义性实例:
// 类型转换二义性测试
class B;
class A {
public:
A() = default;
A(const B &b) {} // 通过B构造A
};
class B {
public:
B() = default;
operator A() { return A(); }; // B可以隐式准换为A
};
A fun1(const A &) { return A(); }
class C {
public:
C(int i = 0) {};
C(double d) {};
operator int() { return 0; }
operator double() { return 0.0; }
};
void fun2(long double) {}
class LongDouble {
public:
LongDouble(double = 0.0) {}
operator double() { return 0.0; }
operator float() { return 0.0f; }
};
void calc(int) {}
void calc(LongDouble) {}
测试代码:
void AmbiguousConvertTest() {
LongDouble ldObj;
// int ex1 = ldObj; // 二义性
float ex2 = ldObj; // OK,确定为float转换
double dval;
calc(dval); // 调用calc(int),而不是calc(LongDouble),为啥???
// 实参匹配和相同的类型转换
B b;
A a = fun1(b); // 没有出现二义性??? 调用了B类的转换符
// 转换目标为内置类型的多重类型转换
C c1;
// fun2(c1); // 二义性错误,无法确定调用哪个转换函数
fun2(static_cast<int>(c1));
fun2(static_cast<double >(c1));
long lg = 0;
// C c2(lg); // 二义性错误,无法确定调用哪个构造函数
C c2(int(lg));
C c3(double(lg));
return;
}
参考: C++ Primer 第五版 第14章