模板功能指针作为模板参数

Template function pointer as a template parameter

本文关键字:参数 指针 功能      更新时间:2023-10-16

我定义了一组函数模板:

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
    }

声明第一个模板参数的正确方法是什么?

P.S。我确实知道有一个解决方法可以在班级中包装前三个功能并使它们变得静态。我只想知道是否有一种直接解决问题的方法。

模板模板参数只能是类模板,而不是函数模板,因此您必须将功能模板包装在类模板中:

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

在C 1y中,您可以考虑使用通用lambda简化此功能,尽管这将是函数参数,而不是模板参数:

for_each(..., [](auto t) { foo(t); }, ...);
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上的过载分辨率。

IE,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 );

a上,然后在b上,然后在c等上调用foo,等等。

模板模板参数必须是类。

#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 );
}