2016-08-25 9 views
8

C++ 17では、instantiate objects without specifying the template typesに可能です。基本的には、このコードはコンパイルします:C++で転送参照を使用する場合、テンプレート構造体にstd :: decayが必要ですか?

std::pair p(2, 4.5);  // deduces to std::pair<int, double> p(2, 4.5); 
std::tuple t(4, 3, 2.5); // same as auto t = std::make_tuple(4, 3, 2.5); 

ので、以下のコードを仮定:

template<typename... Ts> 
struct Foo 
{ 
    Foo(Ts&&... ts) : 
     ts{std::forward_as_tuple(ts...)} 
    {} 

    std::tuple<Ts...> ts; 
}; 

int main() 
{ 
    auto f = [] { return 42; }; 
    Foo foo{f, [] { return 84; }}; 
} 

は、私はこのようなタプル宣言でstd::decayを使用する必要がありますか?私はFooののコンストラクタでこのパターンを見ることができます

template<typename T> 
auto make_baz(T&& t) -> baz<std::decay_t<T>>; 

そして、それは転送を使用しています。このため

std::tuple<std::decay_t<Ts>...> ts; 

は、私は推測テンプレートの種類に基づいてオブジェクトを返すように関数を記述したい方法ですタプルに値を正しく渡すための参照。私は、ここでタイプの控除が同じように動作するかどうかはわかりません。

+0

控除ガイドを追加してみませんか? – cpplearner

+0

@cpplearnerすでにFooのインスタンス化のための型減算があります。私は控除ガイドのための利点を見ないか、または私は何かが欠けている? –

答えて

4

クラスの内部を変更して、クラステンプレートの引数の減算を使用する必要はありません。それは控除のためのガイドです。

開始する最も良い場所は、make_X関数を記述することです。あなたが提供するかどうかにかかわらず、希望の署名を決定すると、明示的な控除ガイドを書く必要があるかどうか、またはあなたのコンストラクタから推測された暗黙の控除ガイドに頼ることができます。

実際には、暗黙的であれ明示的であれ、控除ガイドはmake_X関数(コンストラクターelisionをコピーするまで)と同じように動作します。

ご希望makeFooは、次のように宣言しています。これは、テンプレート引数に変換を実行するので、明示的な控除ガイドを提供する必要が

template<typename... Ts> 
auto makeFoo(Ts&&... ts) -> Foo<std::decay_t<Ts>...>; 

を。これはauto makeが削除だけで、makeFooの宣言に構文的に同じです。

template<typename... Ts> 
Foo(Ts&&... ts) -> Foo<std::decay_t<Ts>...>; 

明示的な控除のガイドを提供していない場合は、1があるもの以外の任意の型変換せずに、自分のコンストラクタから生成されますテンプレート引数控除の際に発生します。それはstd::decay_tを適用していないので

template<typename... Ts> 
Foo(Ts&&... ts) -> Foo<Ts...>; 

これは、あなたが望むものではありません。あなたのクラスの内部を変更すると(std::decay_tからtsまで)機能しますが、明示的な控除ガイドで問題が解決されても不要です。

+0

オブジェクトの宣言で型減算が行われると仮定すると、その利点は何ですか? –

+0

申し訳ありませんが、「それ」とはどういう意味ですか?あなたは 'decay_t'など何かを意味しますか? – ecatmur

+0

控除ガイド。 C++ 17では、これはFooのインスタンス生成の直後に行われるため、型を指定する必要はありません。私の質問が不明な場合は申し訳ありません:私が望むのは、左辺値をコンストラクタに渡すと、FooのTの型減算が参照になるかどうかを知ることです。私は私の質問を編集します。 –

関連する問題