在重载的C++运算符中检测自我赋值

3

如果这是一个重复的问题,请原谅我;我已经搜索过了,但正确的术语可能超出了我的理解范围。

我的目标是为某个任意类和重载运算符做一些事情。

x = x op y

希望可以识别它是自我分配的,而不是仅生成一个临时变量,然后直接赋值给x (我不仅仅想重载op=)。有没有办法做到这一点?


7
x = x op y 不是自我赋值。使用 x op y 创建一个新值,将其分配给 x - David G
2
所以你想把 x = x + y 转换成 x += y - ApproachingDarknessFish
3
x op y 可以返回一个包含转换运算符到 x 类型的类。赋值运算符可以特殊处理该类以进行优化。对于这种形式的优化有一个术语,但我目前不幸地无法记住它。 - interjay
@ 0x499602D2 这正是我希望避免的。@ Approaching 是的,但 op + 也必须能够检测到它(即 X += Y 和 X = X + Y 应该调用同一个函数)。 - Michael Chase
1
@KarolyHorvath 完成。 - interjay
显示剩余6条评论
1个回答

2
一种方法是让运算符 A op A 返回另一个类 APlusA 的临时对象,而不执行实际的操作。这个类有一个转换运算符转换为 A,在需要时执行实际计算。
诀窍在于,在类 A 中实现一个接受 APlusA 的临时对象版本的 operator=。如果它识别到正在对同一对象进行操作,则可以在原地执行操作,而无需创建临时的 A 对象。这里是一个示例(ideone上的测试):
#include <iostream>

struct A {
    struct APlusA {
        APlusA(const A&a_, const A&b_) : a(a_), b(b_) {}
        const A &a;
        const A &b;

        operator A() const { 
            std::cout << "Creating temporary A" << std::endl; 
            return A(a.val + b.val);
        }
    };

    A(int val_) : val(val_) {}
    friend APlusA operator+(const A&a, const A&b) { return APlusA(a,b); }
    friend std::ostream &operator<<(std::ostream &s, const A &a) { return s << a.val;}

    A& operator=(const APlusA &apa) {
        if (this == &apa.a) {
            std::cout << "Performing in-place operation" << std::endl;
            val += apa.b.val;
        }
        else
        {
            *this = static_cast<A>(apa);
        }
        return *this;
    }

    int val;
};

使用示例:

int main() {
    A a(4), b(5), c(6);
    std::cout << a+b << std::endl; //Temporary created
    a = b+c;                       //Temporary created
    a = a+b;                       //No temporary - inplace operation
    std::cout << a << std::endl;
    return 0;
}

优化 a = b + c 以避免创建临时变量也是可能的,但我在这里没有这样做。其他可能的优化是处理操作链以避免在每一步都创建一个临时变量。


这正是我在寻找的!我应该在关于链的评论中添加++!太棒了。 - Michael Chase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接