この変数をもう一度参照しない場合、コンパイラはそれを結果の関数オブジェクトに移動できますか?
コンパイラーがコピーをムーブに置き換えることができる唯一の状況は、コピーエリミッションを実行できるのとまったく同じ状況です。これらの状況には、ローカルオブジェクトを値で返すか、または一時的にオブジェクトを初期化することが含まれます。このような場合、コンパイラはソースを作成して同じオブジェクトをターゲットにしてコピーを削除することができます。何らかの理由でコンパイラがそれを行うことができない場合は、ターゲットオブジェクトの適切なコンストラクタを選択するためのオーバーロード解決に関して、ソースオブジェクトを評価値として考慮する必要があります。ただし、あなたの場合、ファイルはLvalueであり、上のケースのどれも適用されません。あなたは明示的な動きを使わなければなりません。
残念ながら、C++ 11には「移動キャプチャ」の構文はありません。 IMHO、それは残念です。しかし、std :: bindはこれをサポートしています。文字列が関数オブジェクトに移動するように
void foo(char const* p) {
string s = p;
auto fun = bind([](string const& s){
...
},move(s));
fun();
}
:このようなラムダ式ではstd ::バインドを組み合わせることが可能でなければなりません。
あなたが意図一度だけ、この関数を呼び出すと、再び関数オブジェクトの外に列を移動したい場合、あなたは非const参照を使用することができます。
void foo(char const* p) {
string s = p;
auto fun = bind([](string & s) {
some_other_func(move(s));
},move(s));
fun();
}
注意あなたがない場合、そのここバインドを使用したいが、ラムダオブジェクトのコンストラクタは、Sのコピーを作成してみましょう、関数オブジェクトの外に列を移動すると、変更可能なキーワードが必要です。そうでない場合は閉鎖型の演算子()関数はconst-になりますので、
void foo(char const* p) {
string s = p;
auto fun = [=]() mutable {
// ^^^^^^^
some_other_func(move(s));
};
fun();
}
を修飾されたものが順番にs
const修飾された文字列。
C++では、ラムダキャプチャ節が少し柔軟になりました。現在
void foo(char const* p) {
string s = p;
auto fun = [s=move(s)]() mutable { // #1
some_other_func(move(s)); // #2
};
fun();
}
場所(some_other_func
が正確に宣言されている方法に応じて)ラムダオブジェクトと#2が移動に#1が移動文字列値を文字列値アウトを書き込むことができます。
私は、これは一般的にコンパイラでは分かりづらいと思います。サンプルコードを提供できますか? – fredoverflow
もちろん、「あたかも同じ」ルールがあります。しかし、私はあなたがコピーctorや移動ctorが副作用を持っているケースを考えていると思いますので、違いを知ることができます。興味深い質問。 – aschepler
@aschepler:正しく呼び出すと、コンパイラーはコピーコンストラクターと移動コンストラクターの副作用を無視できます。 @DeadMG:それは最適化されているように私に見える、あなたはそれを試してみましたか? –