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

时间:2015-06-15 21:23:47

标签: c++ templates

我想知道是否可以将模板函数(或其他)作为参数传递给第二个函数(不是模板)。 向谷歌询问此事似乎只是提供相反的信息(Function passed as template argument

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

我期待的是:

template<class N>void print(A input){cout << input;}
void execute(int input, template<class N>void func(N)){func(input)}

然后再打电话

execute(1,print);

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

2 个答案:

答案 0 :(得分:6)

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

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
}

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

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

现在你可以让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{}); }

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

execute(1, [] (auto&& x) { std::cout << x; });

答案 1 :(得分:0)

执行需要是一个模板 - 编译器无法创建适用于任何输入类型的单个版本的执行。现在,如果您为此特定功能指定了N,例如,如果您将第二个参数打印出来,那么它应该是合法的。