首页 > 解决方案 > c ++如何评估函数列表?

问题描述

我正在创建一个 c++ 库,允许用户评估函数列表。例如,用户将提供三个功能

A mapper1(B);
B mapper2(C);
C mapper3(D);

我将根据输入 D 列表评估它们,检索 A 列表。

功能列表由用户提供。它在编译时是已知的,但我不知道。我如何实现这一点,例如,我应该使用什么数据结构来维护函数列表?

用户使用模板 API 提供功能:

template <typename T>
class Mapper {
public:
    unique_ptr<Mapper<N>> map(function<N(T)>);
}

标签: c++lambdafunctional-programming

解决方案


您可以使用 std::list of command type ,在链接中定义命令类型的函数

http://www.vincehuston.org/dp/command.html

内容总结如下:

  1. 使用类似 execute() 的方法签名定义一个 Command 接口。

  2. 创建一个或多个封装以下子集的派生类:“接收者”对象、要调用的方法、要传递的参数。

  3. 为每个延迟执行请求实例化一个 Command 对象。

  4. 将 Command 对象从创建者(又名发送者)传递给调用者(又名接收者)。

  5. 调用者决定何时执行()。

附上示例:

class Giant {
public:
   Giant()       { m_id = s_next++; }
   void fee()    { cout << m_id << "-fee  "; }
   void phi()    { cout << m_id << "-phi  "; }
   void pheaux() { cout << m_id << "-pheaux  "; }
private:
   int  m_id;
   static int s_next;
};
int Giant::s_next = 0;

class Command {
public:
   typedef void (Giant::*Action)();
   Command( Giant* object, Action method ) {
      m_object = object;
      m_method = method;
   }
   void execute() {
      (m_object->*m_method)();
   }
private:
   Giant* m_object;
   Action m_method;
};

template <typename T>
class Queue {
public:
   Queue() { m_add = m_remove = 0; }
   void enque( T* c ) {
      m_array[m_add] = c;
      m_add = (m_add + 1) % SIZE;
   }
   T* deque() {
      int temp = m_remove;
      m_remove = (m_remove + 1) % SIZE;
      return m_array[temp];
   }
private:
   enum { SIZE = 8 };
   T*  m_array[SIZE];
   int m_add, m_remove;
};

int main( void ) {
   Queue que;
   Command* input[] = { new Command( new Giant, &Giant::fee ),
                        new Command( new Giant, &Giant::phi ),
                        new Command( new Giant, &Giant::pheaux ),
                        new Command( new Giant, &Giant::fee ),
                        new Command( new Giant, &Giant::phi ),
                        new Command( new Giant, &Giant::pheaux ) };

   for (int i=0; i < 6; i++)
      que.enque( input[i] );

   for (int i=0; i < 6; i++)
      que.deque()->execute();
   cout << '\n';
}

// 0-fee  1-phi  2-pheaux  3-fee  4-phi  5-pheaux

推荐阅读