Указатель на функцию шаблона в качестве параметра шаблона

Я определяю набор шаблонов функций:

template < typename type >
void foo ( type object )
{
//  foo the object
}

template < typename type >
void bar ( type object )
{
//  bar the object
}

template < typename type >
void baz ( type object )
{
//  baz the object
}

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

    template < /* ??? */ , typename T , typename... TT >
void for_each ( T parameter , TT... other parameters )
{
// process the first parameter using the function pointer defined by the first template parameter
// recursice call to for_each
}

Как правильно объявить первый параметр шаблона?

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

3

Решение

struct foo_overload_set_t {
template<typename... Ts>
auto operator()(Ts&&... ts) const
-> decltype( foo(std::forward<Ts>(ts)...) ) {
return ( foo(std::forward<Ts>(ts)...) );
}
};
static const foo_overload_set_t foo_overload_set;

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

То есть, foo( a, b, c, d, e ) выполняет тот же код и дает тот же результат, что и foo_overload_set( a, b, c, d, e ) для любого набора аргументов.

Но foo_overload_set является объектом, в то время как foo является неопределенным набором функций, созданных на лету на основе параметров, используемых для его вызова.

Мы можем передать указанный объект вашему for_each:

template<typename OverloadSet>
void for_each( OverloadSet ) {} // do nothing

template < typename OverloadSet , typename T , typename... TT >
void for_each ( OverloadSet overload, T&& parameter , TT&&... other_parameters )
{
overload( std::forward<T>(parameter) );
for_each( overload, std::forward<TT>(other_parameters)... );
}

вызывается как:

for_each( foo_overload_set, a, b, c, d, e );

который продолжает звонить foo на a, Затем на b, Затем на c, так далее.

1

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

Параметры шаблона шаблона могут быть только шаблонами классов, а не шаблонами функций, поэтому вам нужно будет обернуть шаблон функции в шаблон класса:

template<typename T>
struct foo_wrap {
static constexpr void (*fn)(T) = &foo<T>;
};

В C ++ 1y вы можете рассмотреть возможность упорядочения этого с помощью общей лямбды, хотя это будет параметр функции, а не параметр шаблона:

for_each(..., [](auto t) { foo(t); }, ...);
5

Аргументы шаблона должны быть классами.

#include <iostream>

template <typename... T> void ignore( T... ) {}

template < template < typename T > class f_, typename... args_>
void fun( args_&&... args) {
int dummy[] { ( f_<args_>{}( std::forward<args_>(args) ), 0)...};
ignore(dummy);
}

template < typename T >
struct bar {
void operator()( T v )  const {
std::cout << v << " ";
}
};

int main() {
int a{1}, b{2}, c{3};
float d{4.5};
fun<bar>(a, b, c, d );
}
0
По вопросам рекламы [email protected]