2016-04-01 14 views
4

完全な転送は、通常、テンプレートクラスのコンテキストで表示されます。非テンプレートクラスの場合、例えば、それは完璧な転送を使用できるようにコンストラクタのテンプレートメソッド?テンプレート以外のクラスのメソッドの完璧な転送

class Foo() 
{ 
    public: 
     template<typename T> 
     Foo(T &&vec) : memberVec(std::forward<T>(vec)) {}; 

    private: 
     std::vector memberVec; 
}; 

利点は基本的に同じですが、実際のクラスタイプを知っていれば何か違いはありますか?これはいつ良い練習になりますか?

答えて

5

非明示的な1つの引数ctorは変換係数です。 Fooをベクトルから変換可能にしない限り(それは真実かもしれません)、explicitにする必要があります。

一般に、1つの引数を使用すると、SFINAE-Fooの種類が一致しないようにする必要があります。暗黙的なFoo&&Foo const&は、テンプレート番号よりFoo&(例えば、非左辺値)のFooを呼び出すと悪化します。単純なclass=std::enable_if_t<!std::is_same<std::decay_t<T>,Foo>>で十分です。

少しだけコードが生成されます。この場合

std::vector<X>ので

Foo(std::vector<X> vec):memberVec(std::move(vec)) {} 

99%と効率的かつ明確であり、移動する途方もなく安価です。

一般的な転送エラーは、使用時に発生します。上記の例にはそれらがありません - 私はFoo x({1,2,3})となり、{1,2,3}を渡してvecを構成します。 が推測できないので、T&&でそれはできません。

+0

ベクターのコピーが安価であることをどのように知っていますか?ベクトルには数千のXが含まれていました。 – Vincent

+0

@vincが修正されました。申し訳ありませんが、コピー/入力ミス。 – Yakk

関連する問題