13

このテンプレート関数を考えてみましょう:

template<typename ReturnT>
ReturnT foo(const std::function<ReturnT ()>& fun)
{
    return fun();
}

ReturnT渡された呼び出しシグネチャからコンパイラが推測できないのはなぜですか?

bool bar() { /* ... */ }

foo<bool>(bar); // works
foo(bar); // error: no matching function call
4

3 に答える 3

17

タイプの関数ポインタはbool (*)()変換できますがstd::function<bool()>、同じタイプではないため、変換が必要です。コンパイラがその変換が可能かどうかをチェックする前に、ReturnTとして推論する必要boolがありますが、それを行うには、それが可能な変換であることをすでに知っている必要がありますstd::function<bool()>。これは、推論するまで不可能ReturnTです...問題を参照してください。

また、それをbool(*)()変換することもできると考えてstd::function<void()>くださいstd::function<int()>...どちらを推測する必要がありますか?

この単純化を検討してください。

template<typename T>
  struct function
  {
    template<typename U>
      function(U) { }
  };

template<typename T>
  void foo(function<T>)
  { }

int main()
{
    foo(1);
}

コンパイラは、作成したいかどうか、またはfunction<int>それらすべてをいつ作成できるかをどのように知ることができますか?function<char>function<void>int

于 2012-06-19T15:03:34.480 に答える
8
std::function<bool()> bar;

foo(bar); // works just fine

C++ はbar、関数ポインターを受け取るすべてのコンストラクターを見つける前に型を知る必要があるため、関数から戻り値の型を推測できません。

たとえばstd::function<std::string()>、? を取るコンストラクターがないと誰が言いbool (*)()ますか?

于 2012-06-19T15:02:29.263 に答える
1

関数barの型は、bool (*)()C++11 より前の通常の関数型です。私は C++11 には自信がありませんが、コンパイラは と の間の接続をbool (*)()認識const std::function<ReturnT()>&していないと思いReturnT = boolます。

于 2012-06-19T14:44:03.530 に答える