我想将函数值作为模板参数传递给函数。目前我能做的最好的事情是:
template< typename F, F f >
void pass()
{
...
}
...使用的:
pass< decltype(&func), &func >();
我真正想要的是:
pass< &func >();
有没有什么方法可以在没有宏的情况下实现这一点?基本上同时传递类型和值?编译器显然拥有所需的所有信息......
解决方案必须使用可变参数和返回类型。函数值在编译时使用,因此不能作为参数传递。
欢迎使用 C++11 解决方案。
编辑: 用例 - 我在编译时生成绑定(bind),我需要为每个传递的函数创建一个 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 );
}
请注意,我需要创建一个编译时函数包装器,所以我需要在编译时传递函数值。有一些绑定(bind)解决方案允许在运行时进行绑定(bind),但与手写绑定(bind)相比,它们总是需要样板代码。我的目标是在这里实现手写的性能。
最佳答案
现在可以在 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
在您的代码中检测编译器对此的支持。
如果你能够使用 C++20 并且想要更好的错误信息,你也可以使用概念:
template<typename T>
concept CanAddTwoNumbers = std::is_invocable_r_v<int, T, int, int>;
template<auto Func>
requires CanAddTwoNumbers<decltype(Func)>
struct AddTwoNumbersWrapper final
{
auto operator()(int a, int b) const
-> int
{
return std::invoke(Func, a, b);
}
};
int add(int a, int b)
{
return a + b;
}
int main()
{
AddTwoNumbersWrapper<add> wrapper;
return wrapper(12, 34);
AddTwoNumbersWrapper<123> bad; //error: constraint failure
}
关于c++ - 将任何函数作为模板参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24185315/