首页 > 解决方案 > 为人工运算符重载返回引用是否有效?

问题描述

众所周知,我们通常在重载算术运算符时将副本返回给新类。例如,<<运算符通常定义如下:

T1 operator<<(const T1& a, const T2& b) {
    // apply b
    return a;
}

但我想知道在这种情况下返回引用是否通常有效。例如,以下代码是否可能会产生任何无效情况?

T1& operator<<(T1& a, const T2& b) {
    // apply b
    return a;
}

为什么我需要这个?假设我有这样的代码:

class B {
public:
    B() {}
    ~B() { std::cout  << ss_.str() << "\n"; }

    template<typename T>
    B& operator<<(T val) {
        ss_ << val;
        return *this;
    }

private:
    std::stringstream ss_;
};

int main() {
    B{} << "str" << "abc" << 1;
    B{} << "str2" << "abc2" << 2;
}

在这段代码中,类型的构造函数和析构函数T1将只被调用一次,这将非常适合这里。但是,如果我为运算符按值返回,<<则将为每个临时右值调用构造函数和析构函数,这对我的用例来说不是很好。

通过引用返回是否有可能为重载这些运算符创建无效代码?

标签: c++

解决方案


是的,它不仅有效,而且是<<流输出重载时的常见习语。例如:

std::ostream& operator<<(std::ostream& os, const MyData& data) {
  os << data.a << ',' << data.b << ',' << data.c;
  return os;
}

推荐阅读