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

Detect self-assignment in overloaded C++ operators

本文关键字:赋值 运算符 重载 C++ 检测      更新时间:2023-10-16

如果这是重复的,请原谅;我搜索了一下,但正确的方言可能超出了我的理解范围。

我的目标是一些任意类和过载的操作员

x = x op y

会意识到它是自赋值的,而不是直接生成一个临时变量op=到x(我不想重载op=)。有办法做到这一点吗?

实现此操作的一种方法是让A操作A返回另一个类APlusA的临时对象,而不执行操作本身。这个类有一个到A的转换运算符,它在需要时执行实际计算。

诀窍是在类A中实现operator=的一个版本,该版本接受APlusA的临时对象。如果它识别出它正在对同一对象进行操作,那么它就可以在不创建临时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以避免创建临时的,但我在这里还没有这样做。其他可能的优化是处理一系列操作,以避免在每个步骤创建临时操作。