在这种情况下,不能用显式类型转换来解决二义性—— 显式类型转换本身既可以使用转换操作又可以使用构造函数,相反,需要显式调用转换操作符或构造函数:
compute(SmallInt(int_val)); //OK
compute(int_val.operator SmallInt()); //OK
而且,由于某些似乎微不足道的原因,我们认为可能有二义性的转换是合法的。例如,SmallInt类构造函数复制它的Integral实参,如果改变构造函数以接受constIntegral 引用:
class SmallInt
{
public:
SmallInt(const Integral &);
//...
};
则对 compute(int_val)的调用不再有二义性!原因在于使用SmallInt构造函数需要将一个引用绑定到int_val,而使用Integral类的转换操作符可以避免这个额外的步骤。这一小小区别足以使我们倾向于使用转换操作符。
【最佳实践】
避免二义性最好的方法是避免编写互相提供隐式转换的成对的类!
【警告:避免转换函数的过度使用 P460非常精彩的讲述!】
避免二义性最好的方法是,保证最多只有一种途径将一个类型转换为另一类型。做到这点,最好的办法是限制转换操作符的数目,尤其是,到一种内置类型应该只有一个转换。