Почему не работает мой пакет параметров шаблона?

Я пытался получить шаблонную функцию для вызова набора аналогичных функций, чтобы избежать шаблонов.

FooA(float a, Widget* w);
FooB(int b, Widget* w);
FooC(int c, Widget* w);
FooD(int d, int e, Widget* w);

template <typename... Args>
static void RunFoo(void (*foo)(Args..., Widget*), Args... args) {
Widget w
foo(args, &w);
}

Я не понимаю, почему это хорошо работает с:

float a = 10;
RunFoo(FooA, a);

Но это терпит неудачу всякий раз, когда я пытаюсь с несколькими аргументами:

int a = 10;
int b = 3;
RunFoo(FooD, a, b);

Не удается скомпилировать с ошибкой:
msgstr «шаблон кандидата проигнорирован: сбой аргумента шаблона»

Это за пределами возможностей шаблонов с ++?

3

Решение

template<class T>struct tag {using type=T;};
template<class Tag>using type_t=typename Tag::type;
template<class T>using block_deduction=type_t<tag<T>>;

template <typename... Args>
static void RunFoo(block_deduction<void(*)(Args...,Widget*)> foo, Args... args) {
Widget w
foo(args, &w);
}

вы не можете сделать вывод, как Args..., Widget* — пакеты параметров должны быть последними в общем.

Оба случая «равны» в дедукции. block_deduction предотвращает вычет по этому параметру. Таким образом, другой вывод происходит, и работает.

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

Это может быть лучше:

template <class F, class... Args>
static std::result_of_t<F(Args..., Widget*)> RunFoo(F&& f, Args&&... args) {
Widget w
return std::forward<F>(f)(std::forward<Args>(args)..., &w);
}

если вы передаете набор перегрузки, оберните набор перегрузки в объект набора перегрузки. std::result_of_t<?> это C ++ 14, заменить на typename std::result_of<?>::type в C ++ 11.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]