具有不同参数的函数容器 [英] Container of Functions with different Parameters

查看:92
本文介绍了具有不同参数的函数容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以在矢量中存储具有不同参数的void函数?参数的数量总是一个,只有类型不同。参数类型可以是像 int 这样的默认类型,它是指向我自己的对象的指针,如 example * 或任何其他类型。

我现在所做的是使用带有void指针参数的函数向量。所以我可以通过一切。但是我想摆脱所有函数中的背投。

  unordered_map< string,function< void(void *) > >清单; 
$ b $ void Callback(string Name,function< void(void *)> Function)
{
List [Name] .push_back(& Function);
}

回调(事件,[](void * x){
int value = *(int *)x;
cout<值<< endl;
});

下面是一个例子来说明我想要的。请注意我喜欢的模板语法。因此,我需要将所有函数存储在容器中。

  vector< function< void(...)> >清单; //需要一个不同于std向量的东西

模板< typename T>
void Callback(string Name,function< void(T)> Function)
{
List [Name] .push_back(& Function);
}

回调< int>([](int x){
cout<< x<< endl;
});

这个应用程序与性能相关,因为它是实时渲染引擎的重要组成部分。



编辑:我解决了存储没有参数的函数的问题,所以这不再是问题的一部分,是什么让问题变得更加清晰明了。

解决方案

我开发了一个基于无效指针的事件系统,现在它可以工作。它使用模板来传递和接收数据。不支持任何类型的参数或任何类型的参数。由于它使用void指针来存储回调函数,因此与使用boost框架中的任何类型的解决方案相比,它的速度非常快。

  #include< string> 
#include< vector>
#include< unordered_map>
#include< functional>
#include< memory>

使用namespace std;
$ b $ class ManagerEvent
{
typedef unordered_map< string,unordered_map< int,vector< pair< void *,bool> > > >活动;
public:
void Listen(string Name,function< void()> Function)
{
Listen(Name,0,Function);

void Listen(string Name,int State,function< void()> Function)
{
List [Name] [State] .push_back(make_pair(new function< ; void()>(Function),false));
}
模板< typename T>
void Listen(string Name,function< void(T)> Function)
{
Listen< T>(Name,0,Function);
}
模板< typename T>
void Listen(string Name,int State,function< void(T)> Function)
{
List [Name] [State] .push_back(make_pair(new function< void(T )>(Function),true));
}
void Fire(string Name)
{
Fire(Name,0);

void Fire(string Name,int State)
{
auto函数= List [Name] [State]; $ i

for(auto i = Functions.begin(); i!= Functions.end(); ++ i)
{
if(i-> second)continue ;
else(*(function< void()> *)(i-> first))();


void FireRange(String Name,int From,int To)
{
for(int i = From; i< = To; ++ i)火(名,我);
}
模板< typename T>
void Fire(string Name,T Data)
{
Fire(Name,0,Data);
}
模板< typename T>
void Fire(string Name,int State,T Data)
{
auto函数= List [Name] [State]; (i = Functions.begin(); i!= Functions.end(); ++ i)
{
if(i-> second)( *(功能<无效(T)> *)异>首先)(数据);
else(*(function< void()> *)i-> first)();
}
}
私人:
活动列表;
};

这是我想到的,它工作得很好。不过,请随时提出改进建议或将代码用于您自己的项目。


Is there a way to store void functions with different parameters in a vector? The number of parameters is always one, only the type differs. The parameter type can be a default type like int, a pointer to my own object like example* or any other type.

What I do for now is using a vector of functions with a void pointer as parameter. So I can pass everything. But I want to get rid of the back casting in all the functions.

unordered_map<string, function<void(void*)> > List;

void Callback(string Name, function<void(void*)> Function)
{
    List[Name].push_back(&Function);
}

Callback("event", [](void* x){
    int value = *(int*)x;
    cout << value << endl;
});

Here is an example to illustrate what I would like to have. Please note the template syntax I would prefer. Therefore I would need to store all the functions in a container.

vector<function<void(...)> > List; // need something other than a std vector

template <typename T>
void Callback(string Name, function<void(T)> Function)
{
    List[Name].push_back(&Function);
}

Callback<int>([](int x){
    cout << x << endl;
});

This application is performance related since it is an essential part of a realtime rendering engine.

Edit: I solved the point of storing functions without parameters, so this is not part of the question anymore what makes the question more clear and straightforward.

解决方案

I developed a void pointer based event system and it works now. It uses templates for passing and receiving data. Functions with none or one parameter of any type both are supported. Since it uses void pointers to store the callback functions I suppose it is very fast compared to a solution using the any type from boost framework.

#include <string>
#include <vector>
#include <unordered_map>
#include <functional> 
#include <memory>

using namespace std;

class ManagerEvent
{
    typedef unordered_map<string, unordered_map<int, vector<pair<void*, bool> > > > Events;
public:
    void Listen(string Name, function<void()> Function)
    {
        Listen(Name, 0, Function);
    }
    void Listen(string Name, int State, function<void()> Function)
    {
        List[Name][State].push_back(make_pair(new function<void()>(Function), false));
    }
    template <typename T>
    void Listen(string Name, function<void(T)> Function)
    {
        Listen<T>(Name, 0, Function);
    }
    template <typename T>
    void Listen(string Name, int State, function<void(T)> Function)
    {
        List[Name][State].push_back(make_pair(new function<void(T)>(Function), true));
    }
    void Fire(string Name)
    {
        Fire(Name, 0);
    }
    void Fire(string Name, int State)
    {
        auto Functions = List[Name][State];

        for (auto i = Functions.begin(); i != Functions.end(); ++i)
        {
            if(i->second) continue;
            else          (*(function<void()>*)(i->first))();
        }
    }
    void FireRange(string Name, int From, int To)
    {
        for(int i = From; i <= To; ++i) Fire(Name, i);
    }
    template <typename T>
    void Fire(string Name, T Data)
    {
        Fire(Name, 0, Data);
    }
    template <typename T>
    void Fire(string Name, int State, T Data)
    {
        auto Functions = List[Name][State];

        for (auto i = Functions.begin(); i != Functions.end(); ++i)
        {
            if(i->second) (*(function<void(T)>*)i->first)(Data);
            else          (*(function<void()>*)i->first)();
        }
    }
private:
    Events List;
};

This is what came to my mind and it works quite well. However, please feel free to suggest improvements or use the code for your own projects.

这篇关于具有不同参数的函数容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆