Я пытаюсь собрать универсальный метод вызова (для моста C ++ OO / v8), используя метапрограммирование вариационных шаблонов для построения списка параметров, преобразования в нативные типы и, наконец, выполнения присоединенного метода после получения входящего параметра.список пуст (и поэтому создается исходящий текст):
template<typename... PARAMS>
class InvocationBuilder {
public:
void invoke(const Arguments &source, PARAMS&... params) {
cout << "Invoke" << endl;
(instance->*(method))(*params...);
}
template<class HEAD, class ... TAIL>
void invoke(const Arguments &source, PARAMS... params) {
cout << "Expand" << endl;
Type<HEAD> param(source[sizeof...(PARAMS)]);
InvocationBuilder<PARAMS..., HEAD> builder;
builder.template invoke<TAIL...>(source, params..., *param);
}
Класс Type является просто оболочкой для создания стековых вариантов параметров v8 (так что, например, строки char * можно использовать, пока вобласть действия во время вызова, но автоматически очищается после возврата вызова).
Теперь, когда фактический мост вызывает это, со списком параметров, используя:
InvocationBuilder<> builder;
builder.template invoke<ARGS...>(args);
Где аргументыявляется ссылкой v8 :: Arguments.
Компилятор корректно объединяет в цепочку каждый шаг генерации параметра, но не соответствует не шаблонному методу invoke (), чтобы фактически выполнить собственный метод C ++.
Сообщение об ошибке выглядит следующим образом:
include/link/function.hh: In member function 'void sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::InvocationBuilder<PARAMS>::invoke(const v8::Arguments&, PARAMS ...) [with HEAD = int, TAIL = {}, PARAMS = {int, int}, CLASS = SomeClass, ARGS = {int, int, int}]':
include/link/function.hh:65:6: recursively instantiated from 'void sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::InvocationBuilder<PARAMS>::invoke(const v8::Arguments&, PARAMS ...) [with HEAD = int, TAIL = {int}, PARAMS = {int}, CLASS = SomeClass, ARGS = {int, int, int}]'
include/link/function.hh:65:6: instantiated from 'void sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::InvocationBuilder<PARAMS>::invoke(const v8::Arguments&, PARAMS ...) [with HEAD = int, TAIL = {int, int}, PARAMS = {}, CLASS = SomeClass, ARGS = {int, int, int}]'
include/link/function.hh:47:5: instantiated from 'v8::Handle<v8::Value> sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::run(const v8::Arguments&) [with CLASS = SomeClass, ARGS = {int, int, int}]'
test.cc:41:1: instantiated from here
include/link/function.hh:65:6: error: no matching function for call to 'sjs::link::InstanceFunctionVariadic<SomeClass, int, int, int>::InvocationBuilder<int, int, int>::invoke(const v8::Arguments&, int&, int&, int)'
include/link/function.hh:65:6: note: candidate is:
include/link/function.hh:61:10: note: template<class HEAD, class ... TAIL> void sjs::link::InstanceFunctionVariadic<CLASS, ARGS>::InvocationBuilder::invoke(const v8::Arguments&, PARAMS ...) [with HEAD = HEAD, TAIL = {TAIL ...}, PARAMS = {int, int, int}, CLASS = SomeClass, ARGS = {int, int, int}]
Сообщение ясно показывает, что первые три шага, дляМетод void test экземпляра C ++ (int a, int b, int c) работает правильно, извлекает параметры с помощью Type и передает результаты, но я не могу понять, почему последний invoke () не используется правильно.
Я пытался полностью его специализовать, но затем я получаю сообщения об ошибках по поводу специализации вне области пространства имен (что, как я полагаю, связано с тем, что метод является членом шаблонного класса).
Я также попытался сместить списки входящих / исходящих параметров, чтобы входящий входил в шаблон переменной класса, а исходящий - в метод, чтобы вместо этого специализировать класс для вызова - но я сталкиваюсь с сообщением «извините, не реализовано» ораспаковка variadic в статический шаблон.
Я также пытался обойти это, используя общий шаблон с одним variadic, затем специализируясь на случае HEAD / TAIL и специализируясь на случае пустого набора, но затем яполучить немедленную неоднозначность (вероятно, потому что значения HEAD / TAIL на самом деле не роцениваю как параметры - просто в шаблоне).
Но пока без кубиков.У кого-нибудь есть другие идеи, или можете объяснить, где я ошибаюсь?