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 (上記参照) は、アクセス可能または存在するコピー/移動コンストラクターが存在する必要があると述べています。では、ここで何が起こっているのでしょうか?
前もって感謝します!