4

次のコード スニペットで何が起こっているのか混乱しています。ここ本当にmove必要?一時セットを返す最も最適で安全な方法は何ですか?

set<string> getWords()
{
    set<string> words;

    for (auto iter = wordIndex.begin(); iter != wordIndex.end(); ++iter)
    {
        words.insert(iter->first);
    }

    return move(words);
}

私の呼び出しコードは単にset<string> words = foo.getWords()

4

3 に答える 3

6

まず、セットは一時的ではなくローカルです。

第二に、それを返す正しい方法は経由return words;です。

これが戻り値の最適化を可能にする唯一の方法であるだけでなく、さらに、ローカル変数は、コピーが完全に省略されていない (異常な) ケースで、返されたオブジェクトのムーブ コンストラクターにもバインドされます。つまり、これは真のトリプルウィンのシナリオです。

于 2012-10-01T00:45:18.147 に答える
3

ここで move を使用する必要はありません。「単語」を返すだけです。いわゆる「戻り値の最適化」に参加します。

C++11 標準のセクション 12.8 では、ローカル変数が返される場合に移動コンストラクターを呼び出す必要があります (存在する場合)。基本的に、コンパイラは std::move の呼び出しを処理します。

于 2012-10-01T00:48:44.033 に答える
2

いいえ、明示的moveに移動することが必ずしも最適な方法であるとは限りませんsetsetは値によって返されるため、コンパイラは に対して名前付きの戻り値の最適化を実行する場合があります。つまりsetコピーを省略してset、戻り値が格納される呼び出しサイトでインプレースを直接構築する場合があります。明示的な移動はこれを禁止します。

于 2012-10-01T00:44:44.837 に答える