2016-05-10 13 views
4

::std::initializer_listで複数の引数を渡すのは、variadic関数テンプレートメソッドよりも利点がありますか?コードで:: std :: initializer_listとvariadicテンプレート

template <typename T> void f(::std::initializer_list<T> const); 

template <typename ...A> void f(A&& ...args); 

注SFINAE又はstatic_assert()を通して、ならびに単一タイプに制限することができるA...種類あります。引き数は〜を介して繰り返すことができます。

+1

可能な重複:[なぜイニシャライザリストが利用可能なときに、なぜ可変引数を使用するのですか?](http://stackoverflow.com/questions/15465543/why-use-variadic-arguments-now-when-initializer-lists-are- – NathanOliver

+3

あなたが何を求めているのか不明です。イニシャライザーリストでは、同じタイプの引数を値で渡すことができます。テンプレート関数を使用すると、転送参照によって多数の(異なる形式の)型引数を渡すことができます。それらの2つは非常に異なっています。 – SergeyA

+0

@ NathanOliverあなたは私の質問をもっと慎重に読むべきです。 – user1095108

答えて

1

パラメータパックでは使用できない方法でstd::initializer_listを反復処理できます(C++ 17がなく、最初に折りたたむ場合を除く)。例えば、リストにはforのループを持つことができます。パラメータパックの場合、それらを展開するオプションは再帰的な特殊な定義によるものです。

+1

折り畳みは実際にはバリデーションに有利な非常に強い議論です。私は正直言って、この機能をうんざりしています。 – SergeyA

+0

@SergeyAはい、しかし、インデックスのトリックと再帰でも可能です – user1095108

+1

@ user1095108、確かなことです。それは何年もの間これをやってきた方法です:)しかし、折りたたみはとても明白です。だから、lispy! – SergeyA

1

私はあなたと同じように可変的なテンプレート関数を使用していましたが、テンプレート化された可能性があるより多くのパラメータが必要であることに気付きました。その場合、typename... Aはあまりにも熱心で、コールサイトの中カッコに依存して引数のバリデーションリストがどこで終わるか、そして次のオプションの引数がどこで開始されたのかを明確に指定しました。

2

バリデーショナルテンプレートの代わりにinitializer_list<T>を使用すると、いずれかが問題を解決すると仮定すると利点があります。

たとえば、関数定義には非常に多くのパラメータがあります(変数の変更も可能です)。実装には厳しい制限がありますが、標準ではにはが必要です。この制限は256以上にする必要があります。関数呼び出しのパラメータについても同様です。

これに対して、braced-init-listの値の数には、最小限の16Kという制限があります(実装では通常より多くの制限があります)。したがって、ユーザーが巨大な値でこの関数を呼び出すことが合理的であれば、コンパイラが動作することが期待できるのはinitializer_listだけです。

関連する問題