提问人:Pavel Dubsky 提问时间:1/18/2013 最后编辑:Pavel Dubsky 更新时间:5/15/2014 访问量:457
使用强制转换运算符和单参数构造函数的类重载运算符
Overloading operators for class with cast operator and single-argument constructor
问:
我有这样的代码
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;
}
对于类,我有两个错误,如上面的代码所示。上课一切都很好。问题是,我想在生成的类中保留单参数构造函数、强制转换运算符和相等运算(、、),但我只想在类中实现 as 的一个版本。我看不出有什么办法可以做到这一点。这是否可能,或者我必须像在课堂上一样拥有所有三个实现?我知道我为什么会遇到这些错误,我只是不喜欢我拥有的解决方案。Number
Integer
MyClass == int
int == MyClass
MyClass == MyClass
operator==
Number
Integer
答:
2赞
Andy Prowl
1/18/2013
#1
在类中,您定义了一个转换运算符,并且您的构造函数允许将 转换为 .因此,在比较 a 和 an 是否相等时,会出现歧义:编译器应该调用内置的 s 并转换为 ,还是应该选择运算符并转换为 ?两种转换都同样好,它不能选择一个。Number
int
int
Number
Number n
int x
operator ==
int
n
int
x
Number
所以是的,你必须定义三个版本,或者添加一个模板运算符,它可以完美地匹配所有参数的类型,并显式地转发给你的运算符,就像这个一样(但你很可能想用一些来保护它,以限制它的适用性,只限于适当的和):enable_if
T
U
template<typename T, typename U> // beware: this will match anything. to be constrained
bool operator == (T n, U const& u)
{
return (Number(n) == Number(u));
}
评论
0赞
Bart van Ingen Schenau
1/18/2013
这就是为什么您应该谨慎提供隐式转换的主要原因。
0赞
Pavel Dubsky
1/18/2013
我以前从未与enable_if合作过,所以我会试着弄清楚。感谢您的解决方案!
0赞
Lol4t0
1/18/2013
#2
您只能将一个定义为成员函数:operator==
bool operator==(const int& right) const
{
std::cout << "custom\n";
return this->GetValue() == right;
}
然后
n1==n2
:将转换为,并且将使用自定义运算符。n2
int
n1 == n3
:将使用自定义运算符n3==n1
:将使用内置运算符
请注意,您希望 be 能够比较常量 soperator==
const
Number
0赞
Yakk - Adam Nevraumont
1/18/2013
#3
在 C++11 中,您可以显式。operator int
另一种方法是使用 SFINAE 来获得适用于一个或多个 args 的模板,但这是使用火箭筒杀死蚂蚁。==
Number
评论
n3
x
n4
n5
i1
i2
explicit
Number
bool operator==(const Number left, const Number right)
Number == int
int == Number
Number == Number