嵌套的lambda函数

时间:2017-04-24 06:43:02

标签: c++ c++11 lambda

我有以下代码:

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 &'

这完全搞砸了!

3 个答案:

答案 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";
    };
};