LoginSignup
0
1

More than 5 years have passed since last update.

[C++11, C++14] initializer listはテンプレート実引数推定されない

Last updated at Posted at 2015-05-09

initializer listはテンプレート実引数推定されない

initializer listは、テンプレート仮引数がstd::initializer_list<T>でない限り、テンプレート実引数推定で、std::initializer_listを導かない。

14.8.2.5/5 Deducing template arguments from a type
A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list type.

なので次のコードでは、テンプレート実引数の推定に失敗し、他にオーバーロードされた関数がなければ、関数呼び出しに失敗する。

template <typename T>
void f (T) {}

int main () {
    f({1, 2, 3}); // f<std::initializer_list<int>>が呼ばれて欲しいが、コンパイルエラー。
}

ちなみに、関数の戻り値型の推定でもstd::initializer_listは導出できない。
変数宣言でのauto指定子を使った型推定では、std::initializer_listを導出できる。

対策

テンプレート実引数推定に頼らなければ良い。

template <typename T = std::initializer_list<int>>
void f (T) {}

int main () {
    f({1, 2, 3}); // テンプレート実引数の推定に失敗するが、デフォルトテンプレートパラメタが代入される。
}

ただし、この方法では、std::initializer_listのテンプレートパラメタを固定しなければならない。
次の様にすれば、テンプレートパラメタを固定するタイミングを関数呼び出し時にまで遅らせる事ができる。

template <typename S, typename T = std::initializer_list<S>>
void f (T) {}

int main () {
    f<int>({1, 2, 3}); // std::initializr_listのテンプレートパラメタを指定する。
}

ただし、いずれにしてもユーザーが手で型を指定しなければならないので、使い辛い。
上手い方法があれば教えて欲しい。

0
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1