Как генерировать обертки для функций С++?

Я пытаюсь создать общий способ обернуть функции С++ (с другого языка). У меня есть список параметров (и итератор) и конкретная функция С++, которая вызывается в списке параметров. Я пытаюсь найти способ распаковать список параметров в качестве аргументов моей функции.

Мой текущий подход заключается в следующем:

  1. Используйте Boost::FunctionTypes, чтобы получить параметры функции в виде последовательности.
  2. Создайте список Boost::Fusion, который будет содержать значения аргументов, используя значения типов параметров для приведения.
  3. Вызовите функцию с созданным списком с помощью вызова boost::fusion.

Оба шага (1) и (2) кажутся довольно простыми. Однако я не могу понять, как сделать второй шаг (и если это вообще возможно - смешивание времени компиляции и времени выполнения кажется немного странным).

Кто-нибудь знает, как сделать второй шаг или как лучше подойти к этой проблеме?

Я знаю, что Boost::Python должен делать что-то подобное, но код немного запутан, чтобы получить хорошее представление о том, что происходит.

обновить

У меня есть частичное решение, которое работает (по крайней мере) для простых случаев. Есть еще проблемы с обращением со ссылкой.

Надеюсь, кто-то может опубликовать что-то лучшее решение.

Список содержит указатели на базовый класс A, от которого происходят все остальные используемые классы. У меня есть два подкласса B и C, которые содержат разные типы значений (int и string).

Оператор convert берет заданный класс и получает базовое значение. Эти значения собираются преобразованием в последовательность, которая затем передается для вызова.

class A {
public:
    A() {}
    virtual ~A() {} 
};

class B: public A {
protected:
    int value;
public:
    B() {}  
    B(int v): value(v) {}

    int getValue() { return value; }
};

class C: public A {
protected:
   string value;
public:
    C() {}  
    C(const string &v): value(v) {}

    string &getValue() { return value; }
};


// this pattern was copied from the test files from the fusion library
struct convert {
    // keep a reference to the parameter we're going to unpack
    list<A *>::iterator &param;

    convert(list<A *>::iterator &param): param(param) {}

    template<typename Sig>
    struct result;

    template <typename T>
    struct result<convert(T)> {
        typedef T type;
    };

    // this must be specialized in order to properly deal with the return types
    template <typename T>
    T operator ()(T type) const {}  
};

template <>
int convert::operator ()(int type) const {
    B *b = dynamic_cast<B *>(*param++);
    if (b != NULL) return b->getValue();
    throw error("illegal cast");
}

template <>
string convert::operator ()(string type) const {
    C *c = dynamic_cast<C *>(*param++);
    if (c != NULL) return c->getValue();
    throw error("illegal cast");
}

и, наконец, для вызова функции:

// create a parameter list (usually this would be passed to us)
list<A *> params;
params.push_back(new B(2));
params.push_back(new C("test"));

// point to beginning of parameter
list<A *>::iterator pos = params.begin();


// foo is the function we're going to call,
typedef BOOST_TYPEOF(foo) params_type;

// use the parameter list of foo to unpack the parameter list
auto passedParams = fusion::as_list(fusion::transform(function_types::parameter_types<params_type>(), trans(pos)));

// finally, call foo with the sequence that was created by the transform
fusion::invoke(foo, passedParams);

person Abe Schneider    schedule 22.06.2012    source источник
comment
Вы можете найти что-то полезное в моем предыдущем вопросе.   -  person chris    schedule 23.06.2012
comment
@Крис: Спасибо! Одно отличие состоит в том, что я работаю со списком указателей на объект. Однако похоже, что это все еще может работать, если я создам кортеж из списка. Если это так, я думаю, что это может быть более элегантным решением.   -  person Abe Schneider    schedule 23.06.2012
comment
Страуструп написал статью еще в 2000 году, описывающую обертки префикса/суффикса для функции. Взгляните на это. research.att.com/~bs/wrapper.pdf   -  person Specksynder    schedule 23.06.2012
comment
@Specksyner: Спасибо за ссылку. Однако это другой тип переноса, который я пытаюсь сделать — я хочу вызвать функцию с параметрами, указанными в списке. В таких языках, как Python, я мог бы просто сделать: fn(*args) для распаковки аргументов в качестве параметров для fn. Я пытаюсь найти эквивалент для С++.   -  person Abe Schneider    schedule 23.06.2012