我正在构建一个具有稍微不对称添加的类。在投诉到来之前,它必然是不对称的。当两个对象相加时,必须发生转换(需要一些时间的操作),并且转换最自然地发生在正确的被加数上。
为了具体说明这一点,这里有一个正在发生的事情的通用示例......
class Foo {
char _fav;
int _prop;
public:
const char fav() const {return _fav;}
const int prop() const (return _prop;}
void changeFav(char); // complicated method that also changes _prop
void changeProp(int); // straightforward method
}
Foo
operator + (Foo A, Foo B) {
Foo sum;
if (A.fav() != B.fav()) A.changeFav(B.fav);
sum.changeProp(A.prop() + B.prop());
return sum;
}
为了两个Foo
要添加,它们需要具有相同的_fav
,因此必须选择要转换的内容。根据以下详细信息Foo
,最自然的做法是更改左被加数以匹配右被加数。
然而,当做:
Foo A,B,C;
Foo D = A + B + C; // D = (A + B) + C
Foo E = A + (B + C);
if A
已经有相同的了_fav
as C
, then changeFav
被调用两次D
(一旦改变A._fav
to B._fav
然后再次改变(A+B)._fav
to C._fav
)和一次E
(改变B._fav
to C._fav
)。我更喜欢后者,但希望避免强迫用户使用括号进行多次添加。
有没有办法超载关联性operator +
让这一切发生?
你可以进行黑客攻击。您必须使用另一种类型来保存操作的中间结果,然后您可以使用隐式强制转换来评估结果。下面是如何在 C++ 中实现 Python 风格的比较运算符的示例:
#include <vector>
#include <cstdio>
struct S {
S(int x) : val(x) { }
int val;
};
struct Comparison {
std::vector<S> operands;
explicit Comparison(S x)
{
operands.push_back(x);
}
operator S()
{
auto i = operands.begin(), e = operands.end();
S prev = *i;
for (i++; i != e; i++) {
S cur = *i;
if (prev.val >= cur.val)
return S(0);
prev = cur;
}
return S(1);
}
void append(const Comparison &a)
{
operands.insert(
operands.end(),
a.operands.begin(),
a.operands.end());
}
void append(const S &a)
{
operands.push_back(a);
}
};
Comparison operator<(const Comparison &left, const Comparison &right)
{ Comparison result(left); result.append(right); return result; }
Comparison operator<(const Comparison &left, const S &right)
{ Comparison result(left); result.append(right); return result; }
Comparison operator<(const S &left, const Comparison &right)
{ Comparison result(left); result.append(right); return result; }
Comparison operator<(const S &left, const S &right)
{ Comparison result(left); result.append(right); return result; }
int main()
{
S x(0);
x = S(0) < S(1) < S(2) < S(3);
std::printf("0 < 1 < 2 < 3 = %d\n", x.val);
x = S(0) < S(1) < S(3) < S(2);
std::printf("0 < 1 < 3 < 2 = %d\n", x.val);
return 0;
}
然而,在这种情况下,我会很快放弃+
操作员。我会避免使用+
对于任何不结合和交换的运算,因为这是约定+
在数学中。相反,您可以使用可变参数函数(使用模板)来执行所需的计算。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)