简体   繁体   English

为人工运算符重载返回引用是否有效?

[英]Is it valid to return reference for artimetic operator overloading?

As we know, we normally return a copy to a new class when overloading an arithmetic operator.众所周知,当重载算术运算符时,我们通常会将副本返回到新的 class。 As an example, << operator is normally defined like this:例如, <<运算符通常定义如下:

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

But I wonder if it is generally valid to return a reference in this case or not.但我想知道在这种情况下返回引用是否通常有效。 For example, is it possible that following code creates any invalid situation?例如,以下代码是否可能会产生任何无效情况?

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

Why I need this?为什么我需要这个? Let's assume I have a code like this:假设我有这样的代码:

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;
}

In this code, constructor and destructor of type T1 will be called only once which will be really suitable here.在这段代码中,类型T1的构造函数和析构函数将只被调用一次,这将非常适合这里。 But if I return by value for the << operator, constructor and destructor will be called for each temporary rvalues which is not great for my use case.但是,如果我为<<运算符按值返回,则将为每个临时右值调用构造函数和析构函数,这对我的用例来说不是很好。

Is it possible that returning by reference create invalid code for overloading these operators?通过引用返回是否有可能为重载这些运算符创建无效代码?

Yes, it's not only valid, it's a common idiom when overloading << for stream outputs.是的,它不仅有效,而且是 stream 输出重载<<时的常见习惯用法。 For example:例如:

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

The rule about returning a reference is to never return a reference to a function local variable.返回引用的规则是永远不要返回对 function 局部变量的引用。 This also includes function parameters that are passed by value.这还包括按值传递的 function 参数。

It gets a little trickier when dealing with reference parameters.处理参考参数时会变得有点棘手。

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

is problematic since a could be bound to a temporary.是有问题的,因为a可能会绑定到临时变量。 That would mean that you are returning a reference to an object that is going to end at the end of the full expression the function call is in, which could cause trouble.这意味着您正在返回对 object 的引用,该引用将在 function 调用所在的完整表达式的末尾结束,这可能会导致麻烦。

Using使用

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

You stop that from happening as now a can only bind to an lvalue so you don't have to worry about it living past the full expression the function is called in.您可以阻止这种情况发生,因为现在a只能绑定到左值,因此您不必担心它会超过调用 function 的完整表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM