【问题标题】:Generic functions taking generic functions as arguments以泛型函数为参数的泛型函数
【发布时间】:2013-09-04 15:29:57
【问题描述】:

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

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

当然,当与非模板函数一起使用时,它会按预期工作。但是如果我有,例如

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

然后

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

不起作用,因为id 需要一个模板参数。我可以写id&lt;int&gt; 让它工作,但这有点违背目的(正如我所看到的,这意味着如果我想写“过滤器”,我必须为每个通用谓词函数编写一个单独的定义)。使用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);}

有点难看,但现在至少我可以通过函数实际参数化了。

那么,有没有更好的方法来处理以泛型函数作为参数的泛型函数?

【问题讨论】:

  • 而不是写id&lt;int&gt; 你不能代替apply(id&lt;decltype(a),a)&gt; 吗? (可能我没有把握大局,但我想我会问)。

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


【解决方案1】:

此“函子”适用于您的第一个应用版本。

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

稍后

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

【讨论】:

    【解决方案2】:

    在 C++11 中,您可以做的最好的事情是使用带有模板化函数调用运算符的 struct

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

    this 比函数 [pointer] 更可取的原因是它更有可能被内联。使用 C++14,您可以使用 lambda:

    [](auto arg){ ... }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-04
      • 2016-07-17
      • 2018-05-21
      • 2020-09-16
      • 2019-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多