2

C++11 標準では、次のペアが関数に移動されることが保証されていますか?

//objects available: key, value
//corresponding type available: pairtype
//function available: void foo(pairtype pair); copies the pair by default

foo({std::move(key),std::move(value)}); //pair moved?

または、自分で移動する必要がありますか?

foo(std::move(pairtype(std::move(key),std::move(value))); //needed?
4

1 に答える 1

8

初期化子リストは式ではないため、型を持たず、値を生成しません。これは、次のことを意味します。

{std::move(key),std::move(value)}

それ自体はペアを作成しません。初期化子リストは、初期化に使用される単なる構文構造であり、この場合、関数パラメーターはwithおよびas 引数のコンストラクターを直接呼び出すことによって構築されます。pairtypestd::move(key)std::move(value)

関連する一時オブジェクトの作成はありません。注意すべき唯一のことは、explicitリストの初期化を実行するときにコンストラクターが考慮されないことです (たとえば、これは のインスタンスでは機能しませんstd::tuple<>)。

fooこれは、先ほど説明した の呼び出し、つまり次のことを意味します。

foo({std::move(key),std::move(value)}

この呼び出しとは技術的に異なります。

foo(std::move(pairtype(std::move(key),std::move(value)))

ここでは、一時的なものを意図的に作成し、それを関数パラメーターに移動しています (コンパイラは 12.8/31 ごとにこの移動を除外する場合がありますが、これは別の話です)。

std::move()一時変数は右辺値であるため、ここへの呼び出しは不要であることに注意してください。とにかく、関数パラメーターは一時オブジェクトからムーブ構築されます。したがって、次のように書くことができます。

foo(pairtype(std::move(key),std::move(value)))

pairtypeこれはクラス テンプレートのインスタンスになることに注意してください。つまりstd::pair<>、テンプレート引数を手動で指定する必要があります。これを回避するには、次を使用できますstd::make_pair()

foo(std::make_pair(std::move(key),std::move(value)))
于 2013-07-09T17:16:00.170 に答える