46

関数を考えてみましょう:

template<typename T>
void printme(T&& t) {
  for (auto i : t)
    std::cout << i;
}

または、begin()/end() 対応型の 1 つのパラメーターを必要とするその他の関数。

以下はなぜ違法なのですか?

printme({'a', 'b', 'c'});

これらすべてが正当な場合:

printme(std::vector<char>({'a', 'b', 'c'}));
printme(std::string("abc"));
printme(std::array<char, 3> {'a', 'b', 'c'});

これを書くことさえできます:

const auto il = {'a', 'b', 'c'};
printme(il);

また

printme<std::initializer_list<char>>({'a', 'b', 'c'});
4

3 に答える 3

50

printme({'a', 'b', 'c'})テンプレート引数Tを推測できなかったため、最初の行は不正です。テンプレート引数を明示的に指定すると、printme<vector<char>>({'a', 'b', 'c'})またはなどのように機能しprintme<initializer_list<char>>({'a', 'b', 'c'})ます。

引数の型が明確に定義されているため、リストした他の引数は正当です。したがって、テンプレート引数Tは問題なく推測できます。

とのスニペットautoも機能します。これilは、がタイプであると見なされるstd::initializer_list<char>ため、のテンプレート引数をprintme()推測できるためです。


ここでの唯一の「面白い」部分はauto、型を選択することですstd::initializer_list<char>が、テンプレート引数は選択しません。これは、C ++11標準の§14.8.2.5/5が、これがテンプレート引数の非推定コンテキストであると明示的に述べているためです。

関連する引数が初期化子リスト(8.5.4)であるが、パラメーターにstd :: initializer_listがないか、cv修飾されたstd::initializer_listタイプへの参照がない関数パラメーター。[例:

template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T

—終了例]

ただし、を使用するとauto、§7.1.6.4/6は明示的にサポートされますstd::initializer_list<>

イニシャライザがbraced -init-list(8.5.4)の場合、std::initializer_list<U>

于 2012-09-14T20:51:49.847 に答える
12

関数をオーバーロードして、initializer_list型の引数を明示的に取得することもできます。

template<typename T>
void printme(std::initializer_list<T> t) {
  for (auto i : t)
    std::cout << i;
}
于 2012-09-14T23:11:49.787 に答える
5

これは、§ 14.8.2.5/5 で特にカバーされています。

関連付けられた引数が初期化子リストであるが、パラメーターが std::initializer_listcv 修飾された可能性のある std::initializer_list型を持っていないか、参照していない関数パラメーター。[ 例:

template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T

—終わりの例]

機能させるために、テンプレート引数の型を明示的に指定できます。

printme<std::initializer_list<int>>( {1,2,3,4} );
于 2012-09-14T20:33:19.800 に答える