我有以下代码:
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 &)'
P.S。我在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 &'
这完全搞砸了!
答案 0 :(得分:5)
我能够使用以下MVCE在VS 2013上重现相同的错误:
Offset
然后我得到错误:
#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;
}
问题在于MSVC无法处理返回的lambda:当你没有指定返回类型时,它试图将它衰减为常规函数指针。这失败是因为你的lambda确实捕获了元素!
此外,您的修复错误,因为Error 1 error C2440: 'return' : cannot convert from 'main::<lambda_1bc0a1ec72ce6dc00f36e05599609bf6>::()::<lambda_4e0981efe0d720bad902313b44329b79>' to 'std::string (__cdecl *)(const foo &)'
不是std::function<std::string(foo const&)>
的类型,而是您要从中返回的类型。
直接在get_functor
强制嵌入到std::function
返回的lambda将解决您的问题:
get_functor
答案 1 :(得分:3)
将其分解为已知类型的仿函数对象将始终有效:
#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));
}
答案 2 :(得分:1)
在编辑中,get_functor1
是一个lambda,它接受一个bool
参数并返回另一个lambda,
但是您尝试将get_functor1
转换为此函数类型:
std::function<std::string(const foo&)>
这是不兼容的。相反,如果您想避免auto
类型扣除,则应使用:
std::function<std::function<std::string(const foo&)>(bool)>
也就是说,一个带有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";
};
};