5

次のコードは、予想どおり、コンパイルされません

#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 で右辺値を返すことは、ダングリング参照を返すか、コンパイラが特定の最適化を実行できないようにするため、通常はお勧めできません。

説明されているケースは、「右辺値で返さない」という経験則からの数少ない例外の1つですか、それとも問題を別の方法で解決する必要がありますか?

まことにありがとうございます!

4

1 に答える 1

0

このコードは完全に有効で安全です。あなたのオブジェクトはすでに右辺値であるため

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

(move を使用して) 再度 rvalue にキャストしても、コードのセキュリティは変更されません。この場合、NRVO 最適化は行われないため、コードの速度に影響する可能性はほとんどありません。

あなたがそれを定式化するとき、私は「はい、これは規則の例外です」と言うでしょう

また、このルールは普遍的なものではありません。何が起こっているのかを理解していれば (それがこの質問をした理由です)、それではなく自分の良識に頼ることができます。

于 2015-05-22T16:54:18.973 に答える