如何在C ++中创建一个包含不同类型函数指针的容器?

时间:2011-01-15 10:09:18

标签: c++ containers function-pointers virtual-machine genetic-programming

我正在做一个线性遗传编程项目,通过自然进化机制培育和进化计划。他们的“DNA”基本上是一个容器(我成功地使用了数组和向量),它包含了一组可用函数的函数指针。 现在,对于简单的问题,例如数学问题,我可以使用一个类型定义的函数指针,它可以指向所有返回double的函数,并且所有函数都作为参数两次加倍。

不幸的是,这不太实际。我需要能够拥有一个容器,它可以有不同种类的函数指针,比如说一个函数指向一个不带参数的函数,一个函数接一个参数,一个函数返回一些东西等等(你得到了主意)...

有没有办法使用任何类型的容器? 我可以使用包含多态类的容器来做到这一点,而多态类又有各种各样的函数指针吗? 我希望有人可以指导我找到解决方案,因为重新设计我迄今为止所做的一切都会很痛苦。

3 个答案:

答案 0 :(得分:2)

虚拟机的一个典型想法是拥有一个单独的堆栈,用于参数和返回值传递。

你的函数仍然可以是void fn(void)类型,但你可以手动传递和返回参数。

您可以这样做:

class ArgumentStack {
    public:
        void push(double ret_val) { m_stack.push_back(ret_val); }

        double pop() {
             double arg = m_stack.back();
             m_stack.pop_back();
             return arg;
        }

    private:
        std::vector<double> m_stack;
};
ArgumentStack stack;

...所以函数看起来像这样:

// Multiplies two doubles on top of the stack.
void multiply() {
    // Read arguments.
    double a1 = stack.pop();
    double a2 = stack.pop();

    // Multiply!
    double result = a1 * a2;

    // Return the result by putting it on the stack.
    stack.push(result);
}

这可以这样使用:

// Calculate 4 * 2.
stack.push(4);
stack.push(2);
multiply();
printf("2 * 4 = %f\n", stack.pop());

你关注吗?

答案 1 :(得分:1)

你不能把多态函数放在一个类中,因为带有(或返回)不同东西的函数不能以相同的方式使用(具有相同的接口),这是多态所需要的

让一个类为你需要的任何可能的函数类型提供虚函数的想法是可行的,但是(对你的问题一无所知!)它的用法对我来说感觉很奇怪:什么函数会派生类覆盖?你的职能不相关吗?

如果你的函数是不相关的(如果没有理由将它们归为同一类的成员,或者它们是静态函数,因为它们不需要成员变量)你应该选择其他的东西......如果你随机选择你的函数,你可以只有几个不同的容器,一个用于函数类型,只需随机选择一个容器,然后在其中选择一个函数。

你能举例说明你的功能吗?

答案 2 :(得分:1)

你提到的本身可能是由一个容器实现的 std::functionBoost::variant等受歧视的联盟 例如:

#include <functional>
#include <cstdio>
#include <iostream>

struct F {
  virtual ~F() {}
};

template< class Return, class Param = void >
struct Func : F {
  std::function< Return( Param ) >  f;
  Func( std::function< Return( Param ) > const& f ) : f( f ) {}
  Return operator()( Param const& x ) const { return f( x ); }
};

template< class Return >
struct Func< Return, void > : F {
  std::function< Return() >  f;
  Func( std::function< Return() > const& f ) : f( f ) {}
  Return operator()() const { return f(); }
};

static void f_void_void( void ) { puts("void"); }
static int f_int_int( int x ) { return x; }

int main()
{
  F  *f[] = {
    new Func< void >( f_void_void ),
    new Func< int, int >( f_int_int ),
  };

  for ( F **a = f, **e = f + 2;  a != e;  ++ a ) {
    if      ( auto p = dynamic_cast< Func< void >*     >( *a ) ) {
      (*p)();
    }
    else if ( auto p = dynamic_cast< Func< int, int >* >( *a ) ) {
      std::cout<< (*p)( 1 ) <<'\n';
    }
  }
}

但我不确定这是不是你想要的...... 您如何看待Alf P. Steinbach的评论?