传递模板函数作为正常函数的参数

Luk*_*lor 5 c++ templates

我想知道是否可以将模板函数(或其他)作为参数传递给第二个函数(不是模板).询问谷歌这个似乎只提供相反的信息(作为模板参数传递的函数)

我能找到的唯一相关页面是http://www.beta.microsoft.com/VisualStudio/feedbackdetail/view/947754/compiler-error-on-passing-template-function-as-an-argument-to-a-功能与省略号 (不是很有帮助)

我期待的是:

template<class N>void print(A input){cout << input;}
void execute(int input, template<class N>void func(N)){func(input)}
Run Code Online (Sandbox Code Playgroud)

然后打电话

execute(1,print);
Run Code Online (Sandbox Code Playgroud)

那么,这可以完成还是必须为execute()定义另一个模板?

0x4*_*2D2 7

函数模板表示无限重载集,因此除非您具有与特化相兼容的目标类型,否则函数类型的推断总是失败.例如:

template<class T> void f(T);
template<class T> void h(T);

void g() {
    h(f); // error: couldn't infer template argument 'T'
    h(f<int>); // OK, type is void (*)(int)
    h<void(int)>(f); // OK, compatible specialization
}
Run Code Online (Sandbox Code Playgroud)

从上面我们可以看到程序的有效性要求我们为函数模板指定模板参数,一般来说,指定它们并不总是直观的.您可以print使用通用重载调用运算符作为额外的间接级别来创建一个仿函数:

struct print {
     template<typename T>
     void operator()(T&& x) const {
         std::cout << x;
     }
};
Run Code Online (Sandbox Code Playgroud)

现在您可以execute接受任何Callable并使用输入调用它:

template<class T, class Op>
void execute(T&& input, Op&& op) {
    std::forward<Op>(op)(std::forward<T>(input));
}

void g() { execute(1, print{}); }
Run Code Online (Sandbox Code Playgroud)

Generic lambdas(C++ 14)使这更加简洁:

execute(1, [] (auto&& x) { std::cout << x; });
Run Code Online (Sandbox Code Playgroud)