如何创建一个指针来存储任何具有任意数量参数的函数?

How to create a pointer to store any function with any number of arguments?

提问人:Vandour 提问时间:11/15/2023 最后编辑:Vandour 更新时间:11/16/2023 访问量:123

问:

我正在尝试为我的引擎组装一个事件系统。我的想法是将指向我希望 Event 在 Event 结构中执行的函数的指针存储,但到目前为止我还没有成功。 我对通过参数将函数传递给其他函数完全陌生。

我设法把这个放在一起:

decltype(auto) _funcExec(Function&& func, Args&&...args)
{
    return std::forward<Function>(func)(std::forward<Args>(args)...);
}

但这只允许我通过_funcExec函数执行另一个函数。 我需要以某种方式从中创建一个类型:这样我就可以创建我的事件结构的指针成员,并将指针存储到我希望事件结构执行的函数。(Function&& func, Args&&...args)

这个概念是这样的:

struct sEvent {
    std::vector<sEventArg> arg;
    std::function<void()> _storedFunc;
    bool _funcStored = false;

    template <class Function, class ... Args>
    bool storeFunc(Function&& func, Args&&...args)
    {
        if( _funcStored ) return false;

        _storedFunc = std::forward<Function>(func)(std::forward<Args>(args)...);
        _funcStored = true;
        return true;
    }
    auto executeFunc( void )
    {
        if( !_funcStored ) return error();
        return _storedFunc(arg[0].get_int32(), arg[1].get_float); // no instance matches the argument list
    }
};

事件被创建,存储在队列中,当时间到来时,它会执行在创建时传递给它的函数。可以使用不同的函数创建许多事件来执行。目标不是为引擎中的每个函数再编写两个函数(事件的 setter 和事件执行器),我希望通过事件系统执行。

我希望我能全面解释它。

所以我有两个问题。

  1. 这甚至可能吗? 如果是
  2. 如何?:D

谢谢。

啊哈哈哈..答案一直都在那里!这应该有效..

struct sEvent {
    std::function<void()> _storedFunc;
    template <typename Function, typename ...Args>
    bool storeFunc( Function&& func, Args&&...args )
    {
        _storedFunc = std::function<void()>{ [=]() { func( args... ); } };
        return true;
    }
    auto _execFunc( void )
    {
        return _storedFunc();
    }
};

谢谢大家,特别是@Ted Lyngmo和@463035818_is_not_an_ai

编辑:所以在玩了两天之后,我无法给它提供任何函数,有参数,没有参数,void,auto,什么都没有:(

C++ Windows variadic- 函数

评论

6赞 Ted Lyngmo 11/15/2023
您可以使用 并存储一个 lambda 来调用其中的任何函数。std::function<void()>
0赞 TooTone 11/15/2023
取决于你想做什么。您想在将来多次执行事件函数,每次都使用一组不同的参数,还是只执行一次,使用一组固定的参数?
2赞 Sam Varshavchik 11/15/2023
您遇到了两个基本的 C++ 概念:1) 所有对象的类型在编译时必须已知,以及 2) 函数参数是其类型定义的一部分,用于函数和指向它的任何指针。将其组合到混合器中,您将得出以下结论:不可能在 C++ 中定义指向具有一些未指定参数的函数的指针类型,这些参数是在运行时确定的。从根本上说,C++ 根本不是这样工作的。
1赞 Vandour 11/15/2023
@TooTone 我猜很多时候,概念是:事件被创建,存储在队列中,当时间到来时,它执行在创建时传递给它的函数。可以使用不同的函数创建许多事件来执行。目标不是为引擎中的每个函数再编写两个函数(事件的 setter 和事件执行器),我希望通过事件系统执行。如果有意义:)
0赞 Vandour 11/15/2023
@Sam Varshavchik 也许我解释得很糟糕.我只需要存储指向函数的指针,我将实际参数值存储在向量中。我用概念解释更新了原来的问题。

答:

3赞 463035818_is_not_an_ai 11/15/2023 #1

正如评论中提到的,您可以将函数 + 参数转换为 .您遗漏了许多细节,使用您提供的代码,您可以将其转换为以下内容以将 s 存储在某处:std::function<void()>std::function

#include <iostream>
#include <functional>

template <typename Function, typename ...Args>
auto make_function(Function&& func, Args&&...args)
{
    return std::function<void()>{
        [=](){ func(args...); }
    };
}

void foo() { std::cout << "foo\n" ;}
void bar(int x) { std::cout << "bar" << x << "\n"; }

int main() {
    auto f = make_function(foo);
    f();
    auto g = make_function(bar,42);
    g();
}

现场演示

评论

0赞 Vandour 11/15/2023
啊,我明白了..这看起来很有希望,谢谢。要试试看。
0赞 Vandour 11/15/2023
这确实对我引导我找到一个很好的解决方案有很大帮助。谢谢!
1赞 Red.Wave 11/15/2023
重新发明轮子。 在 C++26 中,它可以是std:: function<void> g = std::bind_front(bar, 42);std::bind_front<bar>(42);