1

我想编写另一个流类。以前这样做是这样的:

class MyStream
{
   // ...
};

template <typename T>
MyStream& operator <<(MyStream& s, const T& t) noexcept
{
   std::cout << t;
   return s;
}

void f()
{
   MyStream s;
   s << 666;
}

这次我还需要让它与临时人员一起工作:

void f()
{
   MyStream() << 666;

   MyStream s;
   s << 777;
}

我知道这可以使用右值引用来解决:

template <typename T>
MyStream& operator <<(MyStream&& s, const T& t) noexcept
{
   std::cout << t;
   return s;
}

但是我不明白这样做的含义。

我是否也应该实现传统的左值引用运算符?有什么可能出错的吗?像这样将右值引用转换为左值引用可以吗?

4

1 回答 1

-1

永远不要将右值变成左值。这是悬空引用的最常见原因之一。您可以返回一个右值引用,但这已经是一个错误:

template <typename T>
MyStream&& operator <<(MyStream&& s, const T& t) noexcept
{
   std::cout << t;
   return std::move(s);
}

void foo(){
    auto && o = Mystream{} << 12;
    o << "x" ; //undefined behavior
    }

道德是永远不会返回右值引用,也永远不会将右值变成左值。推论始终是 ref 限定赋值运算符和预递增/预递减运算符。那些不能遵循这个简单规则的人应该改用 Rust,因为它不会为此类错误提供机会。

于 2020-07-20T15:02:25.147 回答