2

次のコードがコンパイルされます。

template<int...>
struct Indices {};

template<int J, int ...I>
void foo(Indices<I...>) {}

int main(int argc, char **argv)
{
  foo<2>(Indices<3,4,5>()); //why does this work?
  return 0;
}

J関数呼び出しでは、パラメーターが2になり、...Iパラメーターが3,4,5?になるように思えます。

しかし、なぜこれが機能するのでしょうか。私は指定2したfoo<2>意味で指定Jしただけ2...I、何も指定しませんでした。引数で指定できる...Iのはなぜですか? Indicesここで使用されているテンプレート メカニズムは何ですか?

更新:現在の回答では、1 つの引数を推定せず (明示的に指定)、他の引数を推定できる理由が説明されていません。これは正確にいつ機能しますか?未定義の動作に依存していないことを願っています。標準は、私が上で行っていることを許可していますか?

4

3 に答える 3

6

パラメーター unpack...Iは、関数の引数からコンパイラーによって推定されます。これをテンプレート実引数推定と呼びます。

以下に、いくつかの単純でありながら有用な例を示します。

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

f(10);   //T is deduced as int
f(10.0); //T is deduced as double
f("10"); //T is deduced as char[3]

標準ライブラリの多くの関数は関数テンプレートであり、多くの場合テンプレート引数が推定されます。以下に一例を示します。

std::vector<int> vi;
std::vector<std::string> vs;
//...
std::sort(vi.begin(), vi.end()); //template argument deduction
std::sort(vs.begin(), vs.end()); //template argument deduction

std::sortこれは関数テンプレートですが、ご覧のとおり、テンプレート引数を明示的に渡しません。これは、関数の引数から、テンプレートの引数がコンパイラ自体によって推定されるためです。

それが役立つことを願っています。

于 2013-07-11T14:25:10.423 に答える