如果类中包含一个或多个类型转换,则必须确保在类类型和目标类型之间只存在唯一一种转换方式。
在两种情况下可能产生多重转换路径。第一种情况是两个类提供相同的类型转换:例如,当A类定义了一个接受B类型对象的转换构造函数,同时B类定义了一个转换目标是A类的类型转换运算符时,我们就说它们提供了相同的类型转换。
第二种情况是类定义了多个转换规则,而这些转换涉及的类型本身可能通过其他类型转换联系在一起。最典型的例子是算术运算符。
通常情况下,不要为类定义相同的类型转换,也不要在类中定义两个及两个以上转换源或转换目标是算术类型的转换。
在下面例子中,我们定义了两种将B转换成A的方法:一种使用B的类型转换运算符、另一种使用A的以B为参数的转换构造函数:
// 最好不要在两个类之间构建相同的类型转换
struct B;
struct A
{
A() = default;
A(const B&); // 把一个B转换成A
};
struct B
{
operator A() const; // 把一个B转换成A
};
A f(const A&);
B b;
A a = f(b); // 二义性错误:含义是f(B::operator A())
// 还是f(A::A(const B&))?
另外如果类定义了一组类型转换,它们的转换源(或者转换目标)类型本身可以通过其他类型转换联系在一起,则同样会产生二义性问题。