为啥我不能将 lambda 传递给这个需要 std::function 的函数? [复制]
Posted
技术标签:
【中文标题】为啥我不能将 lambda 传递给这个需要 std::function 的函数? [复制]【英文标题】:Why can't I pass a lambda to this function which takes a std::function? [duplicate]为什么我不能将 lambda 传递给这个需要 std::function 的函数? [复制] 【发布时间】:2015-01-08 23:01:14 【问题描述】:以下程序是非法的,我想了解原因:
#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 转换为 deduce
收到的 std::function
。为什么在这种情况下编译器无法应用适当的转换?
【问题讨论】:
【参考方案1】:问题在于,虽然接受int
并返回int
的lambda 可以转换 为std::function<int(int)>
,但它的类型不是 @ 987654324@ 但我认为是任意实现定义的类型。
你可以通过告诉编译器你想要什么类型来解决这个问题。然后转换将按预期发生。
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
【讨论】:
谢谢。我知道类型不一样,但我试图理解为什么编译器无法在此处应用适当的转换。 问题不是参数值的转换,而是模板参数的推导。一旦它们被知道(如我给出的第一个 sn-p 中),转换就很好了。我将尝试是否可以在此处查找有效的确切规则。 是的,扣分是问题。这必须是一个精确的推论,否则,一切都会发生:任何专业化可能会或可能不会有必要的转换。 lambda 函数的定义并不是完全任意的,为了记录,但答案的要点是正确的。 @Jared,编译器无法构造std::function
(这只是一个类模板),但它可以为具体的Result
和Arg
构造std::function<Result(Arg)>
。如果您确实为这些提供了具体类型(例如 5gon12eder 所做的 int 和 int ),那么它有一个构造函数,可用于将您的 lambda 对象转换为该类的实例。但是没有类型,它就没有可以尝试的构造函数,因为它没有类型。而且你不能只是概括地推断这些类型。以上是关于为啥我不能将 lambda 传递给这个需要 std::function 的函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
我不能将 lambda 作为 std::function 传递
为啥我不能在 C++14 的 lambda 中移动 std::unique_ptr?