12

次のコードがコンパイルされない理由を説明してください。明らかな回避策は、の1引数のオーバーロードを追加することApplyですが、より単純なものはありますか?

template <typename T>
T Identity(const T& i_val)
  {
  return i_val;
  }

template <typename Val, typename Fn>
Val Apply(const Val& v, Fn fn = Identity<Val>)
  {
  return fn(v);
  }

int main() {
  Apply(42);              // error: no matching function for call to 'Apply(int)'
  Apply(42, Identity<int>); // OK
  return 0;
}
4

3 に答える 3

10

テンプレート引数の推定はそのようには機能しません。デフォルト値から引数のタイプを推定することはできません。ただし、C ++ 11では、デフォルトのテンプレート引数を指定できます。

template <typename Val, typename Fn = Val(&)(Val const &)>
Val Apply(const Val& v, Fn fn = Identity<Val>)
{
   return fn(v);
}
于 2012-08-20T12:37:27.333 に答える
6

呼び出す関数の検索は、次の内容で構成されます。1.テンプレート引数の推定を含む候補のセットを作成する2.最適なオーバーロードを決定する

私が標準を正しく理解していれば、実際の関数の引数(つまり、デフォルトの引数ではない)だけがテンプレートの引数の推定に参加します。したがって、引数から42、コンパイラが推測できるのはVal=だけintです。オーバーロードは候補セットに入りません。デフォルトの引数は調べられません。

于 2012-08-20T12:40:33.877 に答える
0

適用はテンプレート化された関数です。あなたがする必要がありますApply<MyValueType,MyFuncType>(42);

コンパイラーがであると推測することは合理的に期待できValますintが、デフォルトのパラメーターを指定したとしても、関数のタイプを推測することは期待できません。Applyその結果、関数のその宣言を呼び出そうとしているとは推測されません。

于 2012-08-20T12:32:53.417 に答える