创建 lambda 函数的调度程序

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

我正在考虑通过指定成对的

{ID, LAMBDA} 来为服务器创建一个 dispatcher() 函数以供服务器选择。所有ID都是唯一的。假设我有 
send()
receive()
函数支持所有允许的类型,您将如何编写一个
dispatcher()
函数来接收 ID,选择相应的 lambda 函数,接收其参数,调用它并发送结果?对于服务器的不同实例,我将有多个
dispatcher()
实例,每个实例具有不同的功能集,并且我不希望在实现中使用 switch 语句。这是此类应用程序的简化框架(编译器资源管理器演示):

#include <utility>
#include <vector>

template<class T>
auto receive() { return -1; } // for exposition only

void send(auto&& ... values);

template<std::pair...functions>
void dispatcher()
{
    for(auto function_id = 0; function_id != -1;)
    {
        function_id = receive<int>();
        // select function corresponding to function_id
        // receive function arguments
        // invoke function and send return value
    }
}

int main()
{
    dispatcher<{100, []{ return 100;}},
    {1000, [](const std::vector<int>& v){ return v; }}>();
}
c++ lambda
1个回答
0
投票

该解决方案基于以下两个步骤:

  • 首先,我们创建一个折叠表达式(由@Ted Lyngmo 建议) 结果调用与 lambda 对应的

    executor()
    函数 功能ID

  • 其次,我们使用lambda函数特征来确定参数类型 需要接收这些参数,将它们传递给 对应的lambda函数并发送执行结果。

以下代码演示了这种方法(编译器资源管理器演示):

template<class Fn> struct lambda_traits;

template< class R, class G, class ... A >
struct lambda_traits<R(G::*)(A...) const>
{
    using Args = std::tuple<std::remove_cvref_t<A>...>;
};

template<class Fn>
struct lambda_traits : lambda_traits<decltype(&Fn::operator())>{};

template<class Fn>
using lambda_args = typename lambda_traits<std::remove_cvref_t<Fn>>::Args;

template <std::pair function>
auto executor() {
    // receive function arguments for function.first here
    std::cout << "Executing function ID " << function.first << '\n';
    
    std::apply([&](auto&&...args)
    {
        send(std::invoke(function.second,
            receive<std::remove_cvref_t<decltype(args)>>()...));
    }, lambda_args<decltype(function.second)>{});
}

template<std::pair...functions>
void dispatcher()
{
    for(auto function_id : {10, 100})
    {
        //function_id = receive<int>();
        (void)((functions.first == function_id
            &&
        (executor<functions>(), true)) || ...);
    }
}

int main()
{
    dispatcher<{100, []{ return 123;}},
    {10, [](const std::vector<int>& v){ return v; }}>();
}
© www.soinside.com 2019 - 2024. All rights reserved.