如何使用常规函数指针作为模板参数

How to use a general function pointer as a template parameter?

本文关键字:参数 指针 何使用 常规 函数      更新时间:2023-10-16

是否可以使用通用函数指针作为模板参数?函数指针模板可以接受自由函数、成员函数和 lambda 函数。为简单起见,假设函数只有一个参数,例如

template<class ArgumentT, class ReturnT, function* f>
struct A
{
   // f is used somewhere.
};

普通模板参数可以引用函数。

#include <iostream>
template <class ArgT, class RetT, class F>
struct A {
    F f;
public:
    A(F f) : f(f) {}
    RetT operator()(ArgT arg) { return f(arg); }
};
int unchanged(int i) { return i; }
int main(){
    A < int, int, int(*)(int)> t{ unchanged };
    for (int i = 0; i < 10; i++)
        std::cout << t(i) << "n";
}

不过,没有什么将模板参数限制为函数 - 您可以轻松地使用一些重载operator()的类,并调用它(事实上,这通常是可取的)。

我建议使用 std::function<>如果你可以使用 C++11 或 boost::function<>如果你不能:

template<class ArgumentT, class ReturnT > struct A { 
    typedef std::function< ReturnT( ArgumentT ) > Function;
    void foobar( Function f ) { ReturnT ret = f( arg ); }
};

在这种情况下,您可以传递函数指针、函子、lambda,或者将 std::bind 或 boost::bind 与几乎任何签名不匹配的函数一起使用。我不确定在这种情况下您是否需要模板,您可以直接使用 std::function,但这取决于您的代码。

您正在组合类型和数据,您需要更像:

template<class ArgumentT, class ReturnT, typename F*>
struct A {
    //use F* to refer to f somewhere
};

你可以实现一些接近的东西:

template<class ArgumentT, class ReturnT, class F, F f>
struct A;
template<class ArgumentT, class ReturnT, ReturnT (*f)()>
struct A<ArgumentT, ReturnT, ReturnT (*)(), f>
{
   // f is used somewhere.
};
template<class ArgumentT, class ReturnT, class C, ReturnT (C::*f)()>
struct A<ArgumentT, ReturnT, ReturnT (C::*)(), f>
{
   // f is used somewhere.
};

。但是,您不能将std::function<ReturnT ()>之类的东西作为非类型模板参数。函数指针的专用化也将接受非捕获 lambda。