需要某种方法将函数存储在列表中,然后调用它们

发布于 2024-12-06 14:26:40 字数 152 浏览 0 评论 0原文

这个列表必须包含函数,它们可能来自不同的命名空间,甚至是实例化类的方法。
然后将迭代该列表并调用所有函数和方法。如果它们也可以包含参数,那就太好了。

我正在考虑使用 std::vector,但我怀疑我的猜测远不正确。

您推荐我什么方法?欢迎所有帮助。

This list, has to hold functions, they might be from different namespaces and even methods of instanced classes.
This list will then be iterated and all the functions and methods called. It would be nice if they could contain arguments also.

I was thinking on using a std::vector, but I suspect that I am far from correct in that guess.

What approach do you recommend me? All help is welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

记忆里有你的影子 2024-12-13 14:26:40

如果您的编译器已经支持 std::function 和 std::bind ,您可以使用它。

#include <functional>
#include <vector>

void x(int) {}
void y() {}
class Z {
public:
    void z() {}
};

int main(int argc, char *argv[])
{
    typedef std::function<void ()> VoidFunc;
    typedef std::vector<VoidFunc> FuncVector;
    FuncVector functions;

    functions.push_back(std::bind(&x, 1));
    functions.push_back(&y);
    Z z1;
    functions.push_back(std::bind(&Z::z, z1));

    for(FuncVector::iterator i = functions.begin(); i != functions.end(); i++) {
        (*i)();
    }

    return 0;
}

You could use std::function and std::bind if your compiler already supports it.

#include <functional>
#include <vector>

void x(int) {}
void y() {}
class Z {
public:
    void z() {}
};

int main(int argc, char *argv[])
{
    typedef std::function<void ()> VoidFunc;
    typedef std::vector<VoidFunc> FuncVector;
    FuncVector functions;

    functions.push_back(std::bind(&x, 1));
    functions.push_back(&y);
    Z z1;
    functions.push_back(std::bind(&Z::z, z1));

    for(FuncVector::iterator i = functions.begin(); i != functions.end(); i++) {
        (*i)();
    }

    return 0;
}
心在旅行 2024-12-13 14:26:40

让所有函数都实现 命令模式。

当您

std::list<Command>

迭代列表中,您调用每个列表项的 Execute() 方法。

例如,假设您有一个名为 Commander 的简单命令界面:

class Commander
{
public:
    virtual        ~Commander;

    virtual void    Execute();//= 0;
};

并且您想要将三个对象放入列表中:灰狗、灰隼和女朋友。将每个对象包装在调用该对象感兴趣的函数的 Commander 对象中。灰狗奔跑:

class RunGreyhound: public Commander
{
public:
    void            Execute()
                    {
                        mGreyhound->Run();
                    }
private:
    Greyhound*      mGreyhound;
};

灰隼飞翔:

class RunGyrefalcon: public Commander
{
public:
    void            Execute()
                    {
                        mGyrefalcon->Fly( mGyrefalcon->Prey() );
                    }    
private:
    Gyrefalcon*      mGyrefalcon;
};

女朋友尖叫:

class RunGirlfriend: public Commander
{
public:
    void            Execute()
                    {
                        mGirlfriend->Squawk( mGirlfriend->MyJunk(), mGirlfriend->Mytrun() );
                    }
private:
    Girlfriend*     mGirlfriend;
};

将指挥官对象填入您的列表中。现在您可以迭代它们并调用每个元素的 Execute() 方法:

std::list<Commander> cmdlist;

RunGreyhound dog;
cmdlist.push_back( dog );

RunGyrefalcon bird;
cmdlist.push_back( bird );

RunGirlfriend gurl;
cmdlist.push_back( gurl );

for ( std::list<Commander>::iterator rit = cmdlist.begin(); rit != cmdlist.end(); ++rit )
{
    rit->Execute();
}

Have all of your functions implement the Command Pattern.

Your list becomes a

std::list<Command>

As you iterate over the list, you invoke the Execute() method of each list item.

For example, say you have a simple Command interface called Commander:

class Commander
{
public:
    virtual        ~Commander;

    virtual void    Execute();//= 0;
};

And you have three objects that you want to put in your list: A Greyhound, a Gyrefalcon, and a Girlfriend. Wrap each in a Commander object that calls the object's function of interest. The Greyhound runs:

class RunGreyhound: public Commander
{
public:
    void            Execute()
                    {
                        mGreyhound->Run();
                    }
private:
    Greyhound*      mGreyhound;
};

The Gyrefalcon flies:

class RunGyrefalcon: public Commander
{
public:
    void            Execute()
                    {
                        mGyrefalcon->Fly( mGyrefalcon->Prey() );
                    }    
private:
    Gyrefalcon*      mGyrefalcon;
};

And the Girlfriend squawks:

class RunGirlfriend: public Commander
{
public:
    void            Execute()
                    {
                        mGirlfriend->Squawk( mGirlfriend->MyJunk(), mGirlfriend->Mytrun() );
                    }
private:
    Girlfriend*     mGirlfriend;
};

Stuff the Commander objects in your list. Now you can iterate over them and invoke each element's Execute() method:

std::list<Commander> cmdlist;

RunGreyhound dog;
cmdlist.push_back( dog );

RunGyrefalcon bird;
cmdlist.push_back( bird );

RunGirlfriend gurl;
cmdlist.push_back( gurl );

for ( std::list<Commander>::iterator rit = cmdlist.begin(); rit != cmdlist.end(); ++rit )
{
    rit->Execute();
}
为人所爱 2024-12-13 14:26:40

如果您不想使用现有的解决方案(例如 boost::function),则需要创建一个表示函数的基类,然后创建包装各种函数源的派生类。例如:

#include <iostream>
#include <list>
using std::cout;
using std::list;

struct Function {
  virtual ~Function() { }
  virtual void operator()() = 0;
};

struct PlainFunction : Function {
  PlainFunction(void (*function_ptr_arg)()) : function_ptr(function_ptr_arg) { }
  virtual void operator()() { (*function_ptr)(); }
  void (*function_ptr)();
};

template <typename T> 
struct MethodFunction : Function {
  MethodFunction(T &obj_arg,void (T::*method_ptr_arg)())
    : obj(obj_arg), method_ptr(method_ptr_arg)
  {
  }
  virtual void operator()() { (obj.*method_ptr)(); }
  T &obj;
  void (T::*method_ptr)();
};

void f()
{
  cout << "Called f()\n";
}

struct A {
  void f() { cout << "Called A::f()\n"; }
};

int main(int argc,char **argv)
{
  list<Function *> functions;
  functions.push_back(new PlainFunction(f));
  A a;
  functions.push_back(new MethodFunction<A>(a,&A::f));
  list<Function *>::iterator i = functions.begin();
  for (;i!=functions.end();++i) {
    (*(*i))();
  }
  while (!functions.empty()) {
    Function *last_ptr = functions.back();
    functions.pop_back();
    delete last_ptr;
  }
}

If you don't want to use an existing solution such as boost::function, you will need to create a base class that represents a function, and then derived classes that wrap various sources of functions. For example:

#include <iostream>
#include <list>
using std::cout;
using std::list;

struct Function {
  virtual ~Function() { }
  virtual void operator()() = 0;
};

struct PlainFunction : Function {
  PlainFunction(void (*function_ptr_arg)()) : function_ptr(function_ptr_arg) { }
  virtual void operator()() { (*function_ptr)(); }
  void (*function_ptr)();
};

template <typename T> 
struct MethodFunction : Function {
  MethodFunction(T &obj_arg,void (T::*method_ptr_arg)())
    : obj(obj_arg), method_ptr(method_ptr_arg)
  {
  }
  virtual void operator()() { (obj.*method_ptr)(); }
  T &obj;
  void (T::*method_ptr)();
};

void f()
{
  cout << "Called f()\n";
}

struct A {
  void f() { cout << "Called A::f()\n"; }
};

int main(int argc,char **argv)
{
  list<Function *> functions;
  functions.push_back(new PlainFunction(f));
  A a;
  functions.push_back(new MethodFunction<A>(a,&A::f));
  list<Function *>::iterator i = functions.begin();
  for (;i!=functions.end();++i) {
    (*(*i))();
  }
  while (!functions.empty()) {
    Function *last_ptr = functions.back();
    functions.pop_back();
    delete last_ptr;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文