【问题标题】:Return "this" as rvalue将“this”作为右值返回
【发布时间】:2015-04-03 08:58:48
【问题描述】:

正如预期的那样,以下代码不会编译

#include <iostream>

class A
{

  public:

    A() = default;
    ~A() = default;

    A(const A&) = delete;
    A(A&&) = delete;

    A& operator=(const A&) = delete;
    A& operator=(A&&) = delete;

    A& operator<<(const int i)
    {
      std::cout << "operator<< called" << std::endl;
      return *this;
    }

};

void foo(A&& a)
{
  std::cout << "foo called" << std::endl;
}

int main()
{
  A a; a << 14;
  foo(std::move(a)); // works fine

  foo(A() << 14);    // does not compile

  return 0;
}

将 A 类更改为

class A
{

  public:

    A() = default;
    ~A() = default;

    A(const A&) = delete;
    A(A&&) = delete;

    A& operator=(const A&) = delete;
    A& operator=(A&&) = delete;

    A& operator<<(const int i) &
    {
      std::cout << "operator<< called on lvalue" << std::endl;
      return *this;
    }

    A&& operator<<(const int i) &&
    {
      std::cout << "operator<< called on rvalue" << std::endl;
      return std::move(*this);
    }


};

使程序编译。但是,使用 std::move 返回右值通常不是一个好主意,因为它会返回悬空引用或阻止编译器进行某些优化。

所描述的案例是经验法则“不按右值返回”的少数例外之一,还是应该以不同的方式解决问题?

非常感谢!

【问题讨论】:

标签: c++11 rvalue-reference this-pointer


【解决方案1】:

此代码完全有效且安全。因为你的对象已经是一个右值了

A&& operator<<(const int i) &&

再次将其转换为右值(使用移动)不会改变代码的安全性。在这种情况下不会进行 NRVO 优化,因此不太可能影响代码的速度。

所以当你制定它时,我会说“是的,这是规则的例外”

此外,这条规则也不是通用的:如果你了解正在发生的事情(这就是你问这个问题的原因),你可以依靠你的直觉而不是它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多