我从这里获得的问题的依据是: 无法从lambda函数推断出模板参数std :: function 。此线程中的问题是:为什么此代码无法将lambda传递给函数:
#include <iostream>
#include <functional>
template <typename T>
void call(std::function<void(T)> f, T v)
{
f(v);
}
int main(int argc, char const *argv[])
{
auto foo = [](int i) {
std::cout << i << std::endl;
};
call(foo, 1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该线程的答案是,因为lambda不是a std::function
。但是为什么这段代码会编译:
#include <iostream>
#include <functional>
template <typename T>
void call(std::function<void(T)> f, T v)
{
f(v);
}
int main(int argc, char const *argv[])
{
auto foo = [](int i) {
std::cout << i << std::endl;
};
call({foo}, 1); // changed foo to {foo}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如链接答案中所述,第一个版本无法编译,因为第一个参数的模板参数推导失败。一个lambda永远不会std::function<void(T)>
。
第二个版本的编译,因为,写作{foo}
,std::function<void(T)>
变成非推测语境。因此,对于第一个参数,推论不再会失败,因为甚至没有尝试过。因此T
,int
仅从第二个参数推导得出,并且调用成功,因为lambda可转换为std::function<void(int)>
。
从[temp.deduct.type]:
非推论上下文是:
- ...
- 函数参数,其关联的参数是初始值设定项列表,但参数不具有为其指定从初始值设定项列表中推论的类型。