次のコードを検討してください。
int three() {
return 3;
}
template <typename T>
class Foo {
private:
T* ptr;
public:
void bar(T& t) { ptr = new T(t); }
void bar(const T& t) { ptr = new T(t); }
void bar(T&& t) { (*ptr) = t; } // <--- Unsafe!
};
int main() {
Foo<int> foo;
int a = 3;
const int b = 3;
foo.bar(a); // <--- Calls Foo::bar(T& t)
foo.bar(b); // <--- Calls Foo::bar(const T& t)
foo.bar(three()); // <--- Calls Foo::bar(T&& t); Runs fine, but only if either of the other two are called first!
return 0;
}
Foo::bar(T&& t)
私の質問は、3 番目のオーバーロードがプログラムをクラッシュさせるのはなぜですか? ここで正確に何が起こっているのですか?t
関数が戻った後、パラメーターは破棄されますか?
T
さらに、テンプレート パラメーターが、非常にコストのかかるコピー コンストラクターを持つ非常に大きなオブジェクトであると仮定しましょう。Foo::ptr
このポインターに直接アクセスしてコピーを作成せずに、RValue 参照を使用して割り当てる方法はありますか?