从std :: function调用签名中减去模板参数

时间:2012-06-19 14:40:56

标签: c++ templates std-function template-deduction

考虑这个模板功能:

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

3 个答案:

答案 0 :(得分:15)

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

答案 1 :(得分:8)

std::function<bool()> bar;

foo(bar); // works just fine

C ++不能从函数bar推导出返回类型,因为它必须知道类型才能找到所有带有函数指针的构造函数。

例如,谁说std::function<std::string()>没有构建者使用bool (*)()

答案 2 :(得分:1)

函数bar的类型为bool (*)()左右,即:普通的C ++ 11之前的函数类型。我对C ++ 11没有那么自信,但我想编译器看不到bool (*)()const std::function<ReturnT()>&之间的连接,即使第一个可以隐式转换为{{1}的第二个}}