42

いくつかの場所で、次のように与えられたコピーおよび移動コンストラクターの推奨される署名を見てきました。

struct T
{
    T();
    T(const T& other);
    T(T&& other);
};

ここで、copyコンストラクターはconst参照を取り、moveコンストラクターはnon-const右辺値参照を取ります。

しかし、私が見る限り、これにより、以下の場合のように、関数からconstオブジェクトを返すときにmoveセマンティクスを利用できなくなります。

T generate_t()
{
    const T t;
    return t;
}

これをVC11BetaでテストするとT、moveコンストラクターではなく、のコピーコンストラクターが呼び出されます。return std::move(t);コピーコンストラクターを使用しても、引き続き呼び出されます。

tconstなので、にバインドするべきではないので、これがどのように意味があるかがわかりますT&&。移動コンストラクター署名での使用const T&&は正常に機能し、理にかなっていますが、otherconstであるため、メンバーをヌルアウトする必要がある場合はメンバーをヌルアウトできないという問題があります。これは、すべてのメンバーがスカラーである場合にのみ機能します。または、正しい署名を持つ移動コンストラクターがあります。

一般的なケースでmoveコンストラクターが呼び出されて、tそもそも非定数になっていることを確認する唯一の方法のように見えますが、私はそれを行うのは好きではありません。Tパフォーマンスを向上させるために、そのフォームに反対する必要があることを知っているクライアント。

ですから、私の質問は2つあると思います。まず、moveコンストラクターはconstまたはnon-constの右辺値参照を取得する必要がありますか?そして第二に:私はこの推論の線に正しいですか?constであるものを返すのをやめるべきだと?

4

4 に答える 4

35

const右辺値以外の参照である必要があります。

オブジェクトが読み取り専用メモリに配置されている場合、その正式な存続期間が間もなく終了しても、オブジェクトからリソースを盗むことはできません。C ++のように作成されたオブジェクトはconst、読み取り専用メモリに保存できます(オブジェクトconst_castを変更しようとすると、未定義の動作になります)。

于 2012-05-26T22:21:40.810 に答える
10

通常、ムーブ コンストラクターは非 const 参照を取る必要があります。

const オブジェクトから移動できる場合は、通常、オブジェクトから「移動」するのと同じくらい効率的にオブジェクトをコピーすることを意味します。この時点では、通常、ムーブ コンストラクターを使用するメリットはありません。

また、移動したい可能性のある変数がある場合、それは非定数である必要があることも正しいです。

私が理解しているように、これが Scott Meyers が C++11 の関数からクラス型のオブジェクトを値で返すというアドバイスを変更した理由です。const 修飾された値でオブジェクトを返すと、一時オブジェクトの意図しない変更を防ぐことができますが、戻り値からの移動も禁止されます。

于 2012-05-26T22:38:27.647 に答える
8

ムーブ コンストラクターは const または非 const 右辺値参照を取る必要がありますか?

非 const 右辺値参照を使用する必要があります。まず第一に、右辺値参照は const 形式では意味がありません。単にそれらを変更したいからです (ある意味で、それらを「移動」したい、自分で内部を参照したい)。

また、それらはconstなしで使用するように設計されており、const 右辺値参照の唯一の用途は、Scott Meyers がこのトークで言及した非常に難解なものであると思います(42:20 から 44:47 まで)。

私はこのような推論で正しいでしょうか? const のものを返すのをやめるべきだと?

これは、私が思うに答えるにはあまりにも一般的な質問です。このコンテキストではstd::forward、rvalue-ness と lvalue-ness および const-ness の両方を保持する機能があり、渡されたものを返す場合に通常の関数が行うように一時的なものを作成することも回避することに言及する価値があると思います。 .

この戻りにより、右辺値参照が左辺値参照に「マングル」されることもあり、通常はそれを望まないため、前述の機能を使用した完全な転送により問題が解決します。

そうは言っても、リンクを投稿した講演をご覧になることをお勧めします。

于 2012-05-26T22:38:39.273 に答える