为什么我不能将lambda传递给这个带有std :: function的函数?

时间:2015-01-08 23:01:14

标签: c++ c++11 lambda

以下程序是非法的,我想了解原因:

#include <functional>
#include <iostream>

template<typename Result, typename Arg>
void deduce(std::function<Result(Arg)> f)
{
  std::cout << "Result: " << typeid(Result).name() << std::endl;
  std::cout << "Arg: " << typeid(Arg).name() << std::endl;
}


int main()
{
  auto f = [](int x)
  {
    return x + 1;
  };

  deduce(f);

  return 0;
}

clang的输出:

$ clang -std=c++11 test.cpp 
test.cpp:48:3: error: no matching function for call to 'deduce'
  deduce(f);
  ^~~~~~
test.cpp:26:6: note: candidate template ignored: could not match 'function<type-parameter-0-1 (type-parameter-0-0)>' against '<lambda at test.cpp:34:13>'
void deduce(std::function<T2(T1)> f)
     ^
1 error generated.

似乎我应该能够将我的lambda转换为std::function收到的deduce。为什么编译器在这种情况下不可能应用适当的转换?

1 个答案:

答案 0 :(得分:7)

问题在于,虽然获取int并返回int的lambda可以转换std::function<int(int)>,但其类型为不是 std::function<int(int)>,而是我认为的任意实现定义类型。

您可以通过告诉编译器您想要的类型来解决此问题。然后转换将按预期发生。

auto f = [](int x){ return x + 1; };
deduce<int, int>(f);  // now ok

或者,明确静态类型f

std::function<int(int)> f = [](int x){ return x + 1; };
deduce(f);  // now also ok