传递任何函数作为模板参数

时间:2014-06-12 13:11:40

标签: c++ templates c++11 function-pointers

我想将函数作为模板参数传递给函数。目前我设法做的最好的是:

template< typename F, F f >
void pass()
{
    ...
}

...使用的是:

pass< decltype(&func), &func >();

我真正想要的是:

pass< &func >();

有没有办法在没有宏的情况下实现这一目标?基本上同时传递类型和值?编译器显然拥有所需的所有信息......

解决方案必须使用变量参数和返回类型。函数值在编译时使用,因此不能作为参数传递。

欢迎使用C ++ 11解决方案。


编辑:用例 - 我在编译时生成绑定,我需要为每个传递的函数创建一个C ++函数。这段代码的用例看起来(简化)或多或少像这样:

template < typename F, F f > 
int function_wrapper( lua_State* L ) 
{
    return dispatcher<typename return_type<F>::type>::call( L, 1, f );
}

void register_native_function( lua_Function f, const char* name )
{
    // binding call using pure C function f
}

template < typename F, F f >
void register_function( const char* name )
{
    register_native_function( function_wrapper< F, f >, name );
}

请注意我需要创建一个编译时函数包装器,所以我需要在编译时传递函数值。有一些绑定解决方案允许在运行时绑定,但与手写绑定相比,它们总是需要样板代码。我的目标是在这里实现手写性能。

3 个答案:

答案 0 :(得分:15)

我认为缩短目前这是不可能的。一年前,C ++委员会考虑http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3601.html来解决这个问题,他们鼓励作者在C ++ 14发布后继续追求它。

答案 1 :(得分:6)

现在可以在C ++ 17中使用template<auto>

template<auto Func>
struct FuncWrapper final
{
    template<typename... Args>
    auto operator()(Args &&... args) const
    {
        return Func(std::forward<Args>(args)...);
    }
};

int add(int a, int b)
{
    return a + b;
}

int main()
{
    FuncWrapper<add> wrapper;
    return wrapper(12, 34);
}

演示:https://godbolt.org/g/B7W56t

您可以使用#ifdef __cpp_nontype_template_parameter_auto在代码中检测编译器对此的支持。

答案 2 :(得分:0)

您需要为要作为指针传递的任何函数类型创建一个typedef,如下所示:

typedef int (*MyFunctionType)(int);

template <typename FunctionTypedef, typename ReturnType, typename ParameterType>
ReturnType callFunction(FunctionTypedef functionPointer, ParameterType i)
{
  static MyFunctionType myFunctionPointer = functionPointer;
  return (*functionPointer)(i);
}
int myFunction(int i)
{
}


int main()
{
  int i = 7;
  MyFunctionType myFunctionPointer = myFunction;
  return callFunction<MyFunctionType, int, int>(myFunctionPointer, i);
}

编辑:如果你想存储这些任意类型的函数指针,那么创建一个带有虚拟“调用函数”函数的基类,以及一个实现这个函数的模板化派生类。