嵌套的 lambda 函数
Nested lambda function
我有以下代码:
auto get_functor = [&](const bool check) {
return [&](const foo& sr)->std::string {
if(check){
return "some string";
}
return "another string"
};
};
run(get_functor(true));
run
函数签名:
void run(std::function<std::string(const foo&)> func);
我收到以下错误,这对我来说不太清楚:
error C2440: 'return' : cannot convert from 'main::<lambda_6dfbb1b8dd2e41e1b6346f813f9f01b5>::()::<lambda_59843813fe4576d583c9b2877d7a35a7>' to 'std::string (__cdecl *)(const foo &)'
附言我在 MSVS 2013 上
编辑:
如果我通过将auto
替换为真实类型来编辑代码:
std::function<std::string(const foo&)> get_functor1 = [&](const bool check) {
return [&](const foo& sr)->std::string {
if (check) {
return "some string";
}
return "another string";
};
};
run(get_functor1(true));
我收到另一个错误:
error C2664: 'std::string std::_Func_class<_Ret,const foo &>::operator ()(const foo &) const' : cannot convert argument 1 from 'bool' to 'const foo &'
这完全搞砸了!
我能够使用以下MVCE在VS 2013上重现相同的错误:
#include <iostream>
#include <functional>
#include <string>
struct foo {};
std::string run(std::function<std::string(foo const&)> f) {
return f(foo());
}
int main() {
auto get_functor = [&](bool const check) {
return [=](foo const&) -> std::string { // Line of the compiler error
if (check) {
return "CHECK!";
}
else {
return "NOT CHECK!";
}
};
};
std::cout << run(std::function<std::string(foo const&)>(get_functor(true)));
return 0;
}
然后我得到错误:
Error 1 error C2440: 'return' : cannot convert from 'main::<lambda_1bc0a1ec72ce6dc00f36e05599609bf6>::()::<lambda_4e0981efe0d720bad902313b44329b79>' to 'std::string (__cdecl *)(const foo &)'
问题在于 MSVC 无法处理返回的 lambda:当您不指定返回类型时,它会尝试将其衰减为常规函数指针。这失败了,因为您的 lambda 确实捕获了元素!
此外,您的修复是错误的,因为std::function<std::string(foo const&)>
不是get_functor
的类型,而是您要从中返回的类型。
直接在get_functor
中强制嵌入到返回的 lambda 的std::function
中将解决您的问题:
auto get_functor = [&](bool const check) -> std::function<std::string(foo const&)> {
return [=](foo const&) -> std::string {
if (check) {
return "some string";
} else {
return "another string";
}
};
};
std::cout << run(get_functor(true));
坦率地说,我有时想知道复杂的lambda是否值得费心。
将其分解为已知类型的函子对象将始终有效:
#include <functional>
#include <iostream>
#include <string>
struct foo
{
};
struct foo_functor{
foo_functor(bool check) : check(check) {}
std::string operator()(const foo&) const
{
if (check) {
return "some string";
}
return "another string";
}
const bool check;
};
auto make_foo_functor(bool check) -> foo_functor
{
return foo_functor { check };
}
void run(std::function<std::string(const foo&)> func)
{
foo f;
auto s = func(f);
std::cout << s << std::endl;
}
int main()
{
std::cout << "c++ version: " << __cplusplus << std::endl;
auto get_functor = [&](const bool check) -> foo_functor
{
return make_foo_functor(check);
};
run(get_functor(true));
}
从您的编辑来看,get_functor1
是一个 lambda,它接受单个bool
参数并返回另一个 lambda, 但是您尝试将get_functor1
转换为此函数类型:
std::function<std::string(const foo&)>
这是不兼容的。相反,如果要避免auto
类型扣除,则应使用:
std::function<std::function<std::string(const foo&)>(bool)>
也就是说,一个接受布尔值并返回另一个函数的函数,该函数接受const foo &
并返回std::string
然后get_functor1
变成:
std::function<std::function<std::string(const foo&)>(bool)> get_functor1 = [&](const bool check)
{
return [&](const foo& sr)->std::string {
if (check) {
return "some string";
}
return "another string";
};
};
相关文章:
- 可组合的lambda/std::函数与std::可选
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 如何将lambda作为模板类的成员函数参数
- 我可以将调用类的"this"传递给 lambda 函数吗?
- 模板函数指针和lambda
- 两组使用lambda函数的大括号
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 在构造函数中使用 lambda 的 C++ 类
- 如何调用存储在指向"std::函数"的指针中的 lambda?
- 为什么我不能在 constexpr lambda 函数中使用 std::tuple
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- C++:Lambda 函数指针转换的用例是什么?
- 将有状态的 lambda 传递到 C 样式函数中,而无需上下文参数
- std::映射服装比较函数和函数/lambda错误
- 在可移动类型的构造函数 lambda 中捕获此内容的安全使用
- 排序测试模板化函数 lambda:非法使用此类型作为表达式
- 将匿名函数(lambda)保存为函数类型变量
- 如何编写将自身作为回调传递的匿名函数/lambda