У меня есть функтор, который выглядит так:
struct Functor {
template<typename T, typename... Args> static void func( Args&&... args );
};
Мне нужно передать его как параметр шаблона функции, и эта функция вызывает его:
template<typename F> void fn() {
F::template func<int>(1, 2, 3);
}
fn<Functor>();
Необходимость писать F::template func<int>
кажется утомительной, и мне нужно вызывать ее много раз в разных функциях. Я хотел бы иметь возможность написать что-то более краткое, например, F<int>(1, 2, 3)
.
Есть ли способ его приукрасить?
Вы можете изменить F
следующим образом
template <typename T>
struct Functor {
template<typename... Args> void operator() ( Args&&... args );
};
и получить F
как параметр шаблона-шаблона в fn()
template <template <typename> class F>
void fn ()
{ F<int>{}(1, 2, 3); }
fn<Functor>();
Но я не знаю, хорошая ли это идея: вы сокращаете машинописный текст, но вам нужен экземпляр F<int>
, который не нужен при использовании статического метода.
Кстати, переключаться на operator()
не обязательно, F<int>::func(1, 2, 3)
. (даже если использование operator()
для функтора является обычным явлением).
Другая альтернатива - разрешить вывод всех шаблонов, например:
template <typename> struct tag{};
struct Functor {
template<typename T, typename... Args> static void func(tag<T>, Args&&... args );
};
Итак, использование аналогично:
template<typename F> void fn() {
F::func(tag<int>{}, 1, 2, 3);
}
fn<Functor>();
Хорошая идея! Почему проблематично создать экземпляр
F<int>
? Я уверен, что компилятор оптимизирует его. Я попробую немного поиграть с этим и приму ответ, если решу пойти с ним :)