如何在 C++ 中将参数包传递给 void 指针?

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

请考虑以下代码示例:

#include <functional>
#include <iostream>

template <typename... Ts>
class SomeClass
{
public:
    std::function<bool(Ts...)> some_func;

    void run(Ts... args)
    {
        this->some_func(args...); // this works

        this->thread_run((void *)&this->some_func, args); // this won't work, can't pass the parameter pack
    }

    static void thread_run(void *func_ptr, void *args_ptr)
    {
        auto thread_func = *(std::function<bool(Ts...)> *)(func_ptr);
        thread_func(2, 3);
    }
};

int main()
{
    SomeClass<int, int> a;

    a.some_func = [](int x, int y)
    { std::cout << "Arguments: " << x << " " << y << std::endl; return x > y; };

    a.run(2, 3);

    return 0;
}

如您所见,有一个类具有模板 std::function 成员变量。我可以通过给它一个必须返回 bool 但可以有任意数量的参数的 lambda 表达式来设置它,这很好!

可悲的是,我现在面临的任务是使用给定的线程库(这是不可协商的)将这个函数作为线程运行。线程库的入口函数必须是具有以下签名

void (*thread_entry_t)(void *p1, void *p2)
的静态函数。我已经设法将 std::function 变量传递给示例中的静态函数,请参阅
thread_run
函数,但我找不到通过 void 将参数包
args
传递给静态函数的方法指点一下。

我该怎么办?

c++ variadic-templates std-function
2个回答
0
投票

您可以将参数存储在

tuple
中,并通过
std::apply

将参数转发给函数
template <typename... Ts>
class SomeClass
{
    using ArgTuple = std::tuple<Ts...>;
    using FuncType = std::function<bool(Ts...)>;
public:
    FuncType some_func;

    void run(Ts... args)
    {
        this->some_func(args...);
        auto args_tup = ArgTuple(std::move(args)...);
        this->thread_run((void*)&this->some_func, &args_tup);
    }

    static void thread_run(void *func_ptr, void *args_tuple_ptr)
    {
        auto thread_func = *(FuncType*)(func_ptr);
        auto args_tup = *(ArgTuple*)args_tuple_ptr;
        std::apply(thread_func, args_tup);
    }
};

0
投票

您可以将

args...
包装在一个元组中,并传递一个指向它的指针。我已将其设为类的成员,以便它与
std::function
对象具有相同的生命周期。

template <typename... Ts>
class SomeClass
{
public:
    std::function<bool(Ts...)> some_func;
    std::tuple<Ts...> args;

    void run(Ts... args)
    {
        this->args = { args... };    
        thread_run((void *)&this->some_func, (void *)&this->args);
    }

    static void thread_run(void *func_ptr, void *args_ptr)
    {
        auto & thread_func = *(std::function<bool(Ts...)> *)(func_ptr);
        auto & args = *(std::tuple<Ts...> *)(args_ptr);
        std::apply(thread_func, args);
    }
};
© www.soinside.com 2019 - 2024. All rights reserved.