Итак, я недавно построил систему делегатов, используя вариабельные шаблоны c ++ 11, и она работает просто как прелесть.
Однако в системе, которую я построил, аргументы для функций даются во время создания (как мне хотелось бы), но теперь я также хотел бы иметь возможность передавать некоторое (переменное) количество аргументов во время вызова. Чтобы добиться этого, я пошел и переделал свой код, однако вот где я получаю проблемы;
error: parameter packs must be at the end of the parameter list
sorry, unimplemented: cannot expand ‘Arguments ...’ into a fixed-length argument list
error: type/value mismatch at argument 1 in template parameter list for ‘template<<declaration error>, class ... Params> class FunctionDelegate’
… и многое другое, так что вот фрагмент, который породил проблему;
template<typename... Params>
class Runnable
{
public:
virtual void invoke(tuple<Params...> params) = 0;
virtual ~Runnable()
{
}
};
Это родительский класс для моих двух делегатов (FunctionDelegate и ObjectDelegate). Раньше это был незаполненный класс (так как invoke не принимал никаких аргументов), однако, поскольку у меня есть список шаблонов с переменным числом аргументов, мне также пришлось модифицировать свои подклассы (очевидно), и я только добавил еще один вариант шаблон к ним;
template<typename... Arguments, typename... Params>
class FunctionDelegate : public Runnable<Params...>
{
public:
typedef void (*FunctionType)(Arguments..., Params...);
FunctionDelegate(FunctionType function, tuple<Arguments...> args)
: function(function), args(args)
{
}
void invoke(tuple<Params...> params)
{
callFunction(typename gens<sizeof...(Arguments)>::type(), params, typename gens<sizeof...(Params)>::type());
}
private:
template<int... S, int... R>
void callFunction(seq<S...>, tuple<Params...> params, seq<R...>)
{
function(get<S>(args)..., get<R>(params)...);
}
private:
FunctionType function;
tuple<Arguments...> args;
};
Это, однако, не представляется возможным, по крайней мере, так я и подозреваю;
Любая помощь или понимание приветствуется.
Относительно ваших первых двух вопросов (ответы «нет» а также «нет«), пункт 14.1 / 11 стандарта C ++ 11 определяет:
Если параметр шаблона шаблона класса или псевдонима шаблона имеет аргумент шаблона по умолчанию, каждый последующий
Параметр шаблона должен либо иметь заданный по умолчанию аргумент шаблона, либо быть параметром шаблона
пак. Если параметр-шаблона шаблона основного класса или псевдонима является пакетом параметров шаблона,
это должен быть последний шаблон-параметр. Пакет параметров шаблона шаблона функции не должен
сопровождаемый другим параметром шаблона, если этот параметр шаблона не может быть выведен или имеет значение по умолчанию
аргумент (14.8.2). [ Пример:
template<class T1 = int, class T2> class B; // error
// U cannot be deduced or specified
template<class... T, class... U> void f() { }
template<class... T, class U> void g() { }
— конец примера]
Ваш пример явно нарушает предложение, выделенное жирным шрифтом, что запрещает иметь более одного пакета аргументов шаблона в (основном) шаблоне класса.
Нет, вы не можете использовать такой код. Вы можете использовать следующие например
template<typename... Params>
class FunctionDelegate;
или же
template<typename Arguments, typename Params>
class FunctionDelegate;
как предполагает Ксео.
template<typename... Arguments, typename... Params>
class FunctionDelegate<tuple<Arguments...>, tuple<Params...>> :
public Runnable<Params...> { // };