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()>但不是同一类型,所以需要转换。在编译器可以检查该转换是否可能之前,它需要推断ReturnTbool,但要做到这一点,它需要已经知道这std::function<bool()>是一个可能的转换,在它推断之前这是不可能的ReturnT......看到问题了吗?

另外,考虑一下bool(*)()也可以转换为std::function<void()>or 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 (*)()左右的,即:一个普通的 pre-C++11 函数类型。我对 C++11 没有那么自信,但我猜编译器看不到 and 之间的联系bool (*)()const std::function<ReturnT()>&即使第一个可以隐式转换为第二个 for ReturnT = bool

于 2012-06-19T14:44:03.530 回答