3

私はまだテンプレートを見つけようとしています。特殊化ルールについて読みましたが、ここで何が起こっているのかわかりません。

templates.h で次のように定義しました。

#include <iostream>

template <typename foo>
void f(foo p)
{
  std::cout << "one" << std::endl;
}

template <typename bar>
void f(int p)
{
  std::cout << "two" << std::endl;
}

これを含めて、このようにメインで呼び出すと

  f(1);
  f("x");

私は得る

one
one

ここで問題は、int の最初のほうが 2 番目よりも具体的であるのはなぜですか? 少なくともあいまいで、まったく機能しないはずだと思います。

4

4 に答える 4

5

まず、特殊化はありませんが、2 つの別個の無関係なオーバーロードがあります。

次に、2 番目のオーバーロードは、テンプレート引数なしで関数を呼び出し、テンプレート パラメーターを推測する方法がないため、実行不可能ですbar。したがって、最初のオーバーロードのみが実行可能であり、使用されます。


実際の特殊化は次のようになります。

template <>
void f<int>(int p) { /* ... */ }

いっそのこと、オーバーロードに固執します (一般に、テンプレートの特殊化を提供するよりも関数をオーバーロードする方が良いです) が、2 番目のものは非テンプレートにします:

void f(int p) { /* ... */ }
于 2012-08-01T08:39:53.837 に答える
4

2 番目のオーバーロードは、関数の引数に対するテンプレートの依存関係がないため、次のように呼び出す必要があります。

f<std::string>(1);
f<double>(42);
f<SomeType>(1);

2 番目のバージョンを使用することに意味があるかどうかは別の問題です。関数の内部ロジックに何らかの影響を与えるテンプレート パラメーターがあると想像できます。

template <typename SomeType>
int foo(int seed) {
  // instantiate a SomeType and use it to calculate return value
};

int i = foo<Type1>(42);
int j = foo<Type2>(42);

一方、あなたSomeTypeは関数パラメーターになる可能性があります:

template <typename SomeType>
int foo(int seed, const SomeType& s) {
  // use s to calculate return value
};

Type1 t1;
Type2 t2;
int i = foo(42, t1);
int j = foo(42, t2);
于 2012-08-01T08:36:31.530 に答える
1

2 番目のbar引数は関数の引数から推測できず、明示的に指定する必要があります。

f<whatever>(1);
于 2012-08-01T08:37:21.903 に答える
0

「two」を出力するものは、明示的な特殊化として認識されません。これを試してください L

template <>
void f(int p)
{
  std::cout << "two" << std::endl;
}
于 2012-08-01T08:42:16.973 に答える