14.50 1) int ex1 = ldObj; 需要把LongDouble转换为int,LongDouble未定义对应的类型转换运算符,会先把LongDouble转换为double或float,再转为int,operator double()和operator float()都符合要求,产生二义性;
2) float ex2 = ldObj; 与operator float()精确匹配。
14.51 double转换为int是标准类型转换;double转换为LongDouble是用户自定义转换;标准类型优先,所以cal(dval)会调用 void calc(int).
14.52 先列出相关的类型:
class SmallInt {
friend SmallInt operator+(const SmallInt&, const SmallInt&);
public:
SmallInt(int = 0);
operator int() const { return val; }
private:
std::size_t val;
};
struct LongDouble {
LongDouble operator+(const SmallInt&);
LongDouble(double = 0.0);
operator double();
operator float();
};
LongDouble operator+(LongDouble&, double);
SmallInt si;
LongDouble ld;
ld = si + ld;
ld = ld + si;
对于 ld = si + ld; LongDouble无法转换为SmallInt, SmallInt的friend operator+不适用;SmallInt无法转换为LongDouble,LongDouble的成员operator+和非成员operator+都不适用;SmallInt可转换为int,LongDouble可转换为double或float,内置的operator+(int, float)和operator+(int, double)都适用,产生二义性; 对于ld = ld + si; LongDouble无法转换为SmallInt, SmallInt的friend operator+不适用;LongDouble operator+(const SmallInt&)精确匹配,适用;SmallInt无法转换为double,LongDouble operator+(LongDouble&, double)不适用;内置的 operator+(float, int)和operator+(double, int)也可行,但需要类型转换,优先使用LongDouble operator+(const SmallInt&)。
14.53 先看friend SmallInt operator+(const SmallInt&, const SmallInt&),适用,3.14先转为int,再转为SamllInt; 内置的 operator+(int, double)也适用。因此产生二义性。改为:double d = s1 + SmallInt(3.14); 匹配SamllInt的友元函数。