0

cppreferenceでは、

オペランドが関数の戻り値の型と同じクラス型 (cv 修飾を無視) の prvalue である場合、コピー/移動コンストラクターは、return ステートメントに存在するか、またはアクセス可能である必要はありません。

T f() {
    return T();
}

f(); // only one call to default constructor of T

私はこの権利を理解していますか? 上記の例を機能させるためには、少なくとも 1 つのコピーまたは移動コンストラクターを用意する必要がありますか?

私が試したことは次のとおりです。

class Player
{
  //...
  public:
    Player();
    Player(std::string name);
    Player& operator=(const Player&) = delete;
    Player& operator=(Player&& p) = delete;
    Player(const Player& origin) = delete;
    Player(Player&& p) = delete;

    Player getEmptyPlayer() const {
      return Player("Name");
    }
}

//in main:

Player p1("It's Me");
Player p2 = p1.getEmptyPlayer();

このコードがコンパイルされて機能するのはなぜですか? 私の理解では、実際にはメソッド getEmptyPlayer() は、戻るときにオブジェクトをコピーするためにコピーコンストラクターを呼び出す必要があります。コンパイラによる効率の向上により、これは当てはまりませんが、コピー省略 (NRVO) が有効になり、オブジェクトを本来あるべき場所に直接構築し、コピーを作成しません。それにもかかわらず、cppreference (上記参照) は、アクセス可能または存在するコピー/移動コンストラクターが存在する必要があると述べています。では、ここで何が起こっているのでしょうか?

前もって感謝します!

4

2 に答える 2