C ++ lambda回调

问题描述 投票:1回答:1

我正在尝试创建HTTP类,并且我想通过lambdas使用C ++ 11(不是C ++ 14)回调。我有2个可用的模型,第一个可用...但是看起来很丑。我针对的第二个目标是不进行编译(最后出现错误)。

我不能使用std::function,因为这是一个嵌入式项目,并且该模板会生成很多代码。

#include <cstring>

class HTTP
{
public:
    void get1(const char* url, void* context, void (*callback)(void*, const char*) )
    {
        callback(context, "");
    }

    void get2(const char* url, void (*callback)(const char*) )
    {
        callback("");
    }
};

void test()
{
    int k;
    HTTP http;
    http.get1( "http://google.com", &k, [](void* context, const char* s){
        int *k = (int*) context;
        *k = strlen(s);
    });

    // this does not compile, looking for other alternatives
    http.get2( "http://google.com", [&k](const char* s){
        k = strlen(s);
    });
}

gcc(xtensa-esp32-elf-g ++(crosstool-NG crosstool-ng-1.22.0-80-g6c4433a)5.2.0错误)

HttpRequests.cpp: In function 'void test()':
HttpRequests.cpp:29:6: error: no matching function for call to 'HTTP::get2(const char [18], test()::<lambda(const char*)>)'
     });
      ^
HttpRequests.cpp:11:10: note: candidate: void HTTP::get2(const char*, void (*)(const char*))
     void get2(const char* url, void (*callback)(const char*) )
          ^
HttpRequests.cpp:11:10: note:   no known conversion for argument 2 from 'test()::<lambda(const char*)>' to 'void (*)(const char*)'
c++11 lambda callback gcc5.2
1个回答
0
投票

没有捕获列表的Lambda与函数指针兼容,因此您的第一个Lambda可以作为参数传递给get1()。但是,具有捕获列表的lambda无法转换为函数指针,因此无法将其传递给get2()

具有捕获功能的Lambda具有状态,但函数不能具有状态,这就是为什么此类Lambda无法转换为函数指针的原因。

使函数接受任何lambda(或任何可调用对象)的最常见方法是使用函数模板:

class HTTP {

    // ...

    template <typename Callable>
    void get1(const char* url, void* context, Callable callback)
    {
        callback(context, "");
    }

    template <typename Callable>
    void get2(const char* url, Callable callback)
    {
        callback("");
    }
}

作为功能模板,代码大小可能会成为问题。如果那是不可接受的,则保留您当前的功能并将自己限制为永远不要传递使用捕获的lambda。

© www.soinside.com 2019 - 2024. All rights reserved.