c++ - 将任何函数作为模板参数传递

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

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

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
}

演示:https://gcc.godbolt.org/z/ai3WGH

关于c++ - 将任何函数作为模板参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24185315/

相关文章:

c++ - 将 AMD OpenCL 与 mingw 结合使用

javascript - 如何在VueJs模板中创建临时变量?

c++ - 具有模板化函数的类的接口(interface)类

c++ - 在映射中存储没有默认构造函数的不可复制对象 (C++11)

c++ - 未指定 lambda 函数的返回类型时出现段错误

c++ - 如何在不期望的情况下处理方法中的 nullptr?

c++ - 函数定义后 "const -> std::string const&"的含义?

c++ - 如果路径太长,mciSendString 将不会播放音频文件

c++ - 编译时间与运行时递归

C++随机引擎不是真正随机的