我有这样的代码
class Number
{
int m_value;
public :
Number(const int value) :
m_value(value)
{
}
operator const int() const
{
return m_value;
}
int GetValue() const
{
return m_value;
}
};
bool operator==(const Number& left, const Number& right)
{
return left.GetValue() == right.GetValue();
}
class Integer
{
int m_value;
public :
Integer(const int value) :
m_value(value)
{
}
operator const int() const
{
return m_value;
}
bool operator==(const Integer& right) const
{
return m_value == right.m_value;
}
bool operator==(const int right) const
{
return m_value == right;
}
int GetValue() const
{
return m_value;
}
};
bool operator==(const int left, const Integer& right)
{
return left == right.GetValue();
}
int main()
{
Number n1 = 1;
Number n2 = 1;
int x3 = 1;
n1 == n2;
n1 == x3; // error C2666: 'operator ==' : 3 overloads have similar conversions
x3 == n1; // error C2666: 'operator ==' : 2 overloads have similar conversions
Integer i4 = 1;
Integer i5 = 1;
i4 == i5;
i4 == x3;
x3 == i4;
return 0;
}
对于班级Number
,我有两个错误,如上面的代码所示。对于班级Integer
,一切正常。问题是,我想保留结果类单参数构造函数,强制转换操作符和相等操作(MyClass == int
,int == MyClass
,MyClass == MyClass
),但我想只实现一个版本的班级operator==
中的Number
。我认为没有办法做到这一点。这是可能的,还是我必须在课程Integer
中拥有所有三个实现?我知道为什么我会遇到这些错误,我只是不喜欢我的解决方案。
答案 0 :(得分:2)
在课程Number
中,您将转化运算符定义为int
,您的构造函数允许将int
转换为Number
。因此,在比较Number n
和int x
的相等性时,会产生歧义:编译器是否应为operator ==
调用内置int
并转换n
到int
,还是应该选择您的运营商并将x
转换为Number
?两次转换都同样好,而且无法选择。
所以是的,你必须定义三个版本,或者添加一个模板运算符,它可以完全匹配所有参数的类型并显式转发给你的运算符,就像这个一样(但是你很可能想用一些{{1仅将其适用性限制为适当的enable_if
和T
):
U
答案 1 :(得分:0)
您只能将一个operator==
定义为成员函数:
bool operator==(const int& right) const
{
std::cout << "custom\n";
return this->GetValue() == right;
}
然后,
n1==n2
:n2
将转换为int
并将使用自定义运算符。n1 == n3
:将使用自定义运算符n3==n1
:将使用内置运算符注意,您希望operator==
const
能够比较常量Number
答案 2 :(得分:0)
在C ++ 11中,您可以明确operator int
。
另一种方法是使用SFINAE来制作适用于一个或多个==
args的模板Number
,但这是使用火箭筒杀死蚂蚁。