为何Lambda无法赋值给带模板类型的std::function对象?
为什么你的C++模板函数调用会失败?
咱们直接把问题拆明白——你这段代码没法编译运行,核心是模板类型推导规则和Lambda的本质共同作用的结果,和Lambda本身的特性确实有关,具体来说:
1. Lambda不是std::function
首先要明确:Lambda表达式在编译时会生成一个编译器专属的匿名闭包类型,它不是std::function的任何特化版本。std::function是一个通用的函数包装器,可以容纳Lambda、函数指针、functor等可调用对象,但这需要一次隐式类型转换才能完成。
2. 模板推导不会自动做隐式转换
你的函数模板是这样的:
template <typename T> void foo(T input, function<void(T)> func) { func(input); }
当你调用foo(13, [](int input){ cout << input; })时,编译器需要同时推导模板参数T:
- 第一个参数
13是int,所以编译器会推导出T=int; - 但第二个参数是Lambda,它的类型不是
function<void(int),而是那个匿名闭包类型。模板推导的规则是:只会直接匹配参数的原始类型,不会为了让推导成功而进行隐式类型转换。
这时候编译器就懵了:第二个参数的function<void(T)里的T需要和第一个参数的T保持一致,但Lambda没法直接匹配这个function类型,推导过程就失败了。
验证一下:显式指定T就能运行
如果我们手动指定模板参数T=int,写成:
foo<int>(13, [](int input){ cout << input; });
这时候编译器明确知道第二个参数需要的是function<void(int),就会自动把Lambda隐式转换成这个类型,代码就能正常编译运行了——这也反过来证明了问题出在模板推导阶段,而不是Lambda本身不能和std::function配合。
内容的提问来源于stack exchange,提问作者Jonathan Mee
相关产品推荐
相关产品推荐

