コピーを避けたいテンプレートクラスがあります(そうするための潜在的なコストのため)。移動コンストラクターを実装できますが、「テンプレートパラメーター間」の移動も許可したいと思います。これが私がコンパイルしようとしているものです:
template <class T>
class Foo
{
public:
Foo() {}
template <class U> Foo(Foo<U>&&) {}
private:
Foo(const Foo&);
};
Foo<int> f() { Foo<float> y; return move(y); }
Foo<int> g() { Foo<int> x; return x; }
Foo<int> h() { Foo<float> z; return z; }
技術的にfがコンパイルされる理由を理解しています。move(y)のタイプはFoo(float)&&であり、Foo(U)&&を受け取る便利なコンストラクターがあるため、コンパイラーはU=floatが機能することを確認できます。
hはコンパイルされません。zはFoo(float)型であり、U = floatが選択されている場合にmoveコンストラクターを呼び出すことができることを理解するにはFoo(U)&&から遠すぎると思います...
gがコンパイルされる理由はわかりませんが、コンパイルされます。xの型はFoo(int)です。コンパイラはどのようにムーブ演算子を使用することができますか(Foo(int)からFoo(int)&&に暗黙的にキャストすることはできませんか?)
だから私の質問は:ルールは何ですか?なぜhはコンパイルされるのに、gはコンパイルされないのですか?hをコンパイルするためにFooで変更できるものはありますか?
ありがとうございました