给定一个具有多个隐式转换函数(非显式构造函数和转换运算符)的简单类模板,如下例所示:
template<class T>
class Foo
{
private:
T m_value;
public:
Foo();
Foo(const T& value):
m_value(value)
{
}
operator T() const {
return m_value;
}
bool operator==(const Foo<T>& other) const {
return m_value == other.m_value;
}
};
struct Bar
{
bool m;
bool operator==(const Bar& other) const {
return false;
}
};
int main(int argc, char *argv[])
{
Foo<bool> a (true);
bool b = false;
if(a == b) {
// This is ambiguous
}
Foo<int> c (1);
int d = 2;
if(c == d) {
// This is ambiguous
}
Foo<Bar> e (Bar{true});
Bar f = {false};
if(e == f) {
// This is not ambiguous. Why?
}
}
涉及原始类型(bool
、int
)的比较运算符是模棱两可的,正如预期的那样 - 编译器不知道是否应该使用转换运算符来转换左- 将模板类实例转换为原始类型或使用转换构造函数将右侧原始类型转换为预期的类模板实例。
然而,最后一个比较,涉及一个简单的 struct
,并没有歧义。为什么?将使用哪个转换函数?
使用编译器 msvc 15.9.7 测试。
最佳答案
根据[over.binary]/1
Thus, for any binary operator
@
,x@y
can be interpreted as eitherx.operator@(y)
oroperator@(x,y)
.
根据这条规则,在 e == f
的情况下, 编译器只能解释为 e.operator==(f)
,而不是 f.operator==(e)
.所以没有歧义; operator==
您定义为 Bar
的成员根本不是重载解决方案的候选者。
在 a == b
的情况下和 c == d
, 内置候选 operator==(int, int)
(参见 [over.built]/13)与 operator==
竞争定义为 Foo<T>
的成员.
关于c++ - 为什么隐式转换对于非原始类型不模棱两可?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55249017/