将泛型函数作为参数的通用函数

时间:2013-09-04 15:29:57

标签: c++ templates higher-order-functions

我找不到一种很好的方法来定义将泛型函数作为参数的泛型高阶函数。例如,将此尝试用于其中一个最简单的此类函数:

template<typename F, typename A>
auto apply(F f, const A& a) -> decltype(f(a)){return f(a);}

当然,当与非模板函数一起使用时,它可以正常工作。但是,如果我有,例如<​​/ p>

template<typename A>
A id(const A& a){return a;}

然后

int a = 10;
int b = apply(id, a);

不起作用,因为id需要模板参数。我可以写id<int>来使它工作,但那种方法失败了(正如我所看到的,它暗示如果我想写“过滤器”,我必须为每个通用写一个单独的定义谓词函数)。使用std::function或函数指针没有帮助。此外,我尝试制作apply的“模板模板”版本,但在尝试使用它时遇到各种编译器错误:

template<template<typename> class F, typename A>
auto apply2(F<A> f, const A& a)-> decltype(f(a)){return f(a);}

我想出的最好成绩如下:

struct Id{
    template<typename A>
    static A func(const A& a){return a;}
};

template<typename F, typename A>
auto apply(A a)-> decltype(F::func(a)){return F::func(a);}

这有点难看,但现在至少我可以通过函数进行参数化。

那么,有没有更好的方法来执行将泛型函数作为参数的泛型函数?

2 个答案:

答案 0 :(得分:3)

此“功能”适用于您的第一个版本。

struct id
{
    template<typename A>
    A operator ()(const A& a) {return a;}
};

字母

int b = apply(id(), a); // with extra parenthesis to construct the struct.

答案 1 :(得分:1)

在C ++ 11中,你能做的最好的事情是使用带有模板化函数调用操作符的struct

struct ID {
    template <typename T>
    void operator()(T arg) const {
        ...
    }
};

这是一个优于函数[指针]的原因,因为它更可能被内联。使用C ++ 14,您可以使用lambdas:

[](auto arg){ ... }

这只是写上面struct的可爱版本。