传递通用函数以对同构类型进行操作

时间:2019-05-04 21:36:43

标签: c++ c++11 templates c++14

假设我有一个由同类类型组成的类:

struct Homog {
    int a;
    double b;
    std::string c;
};

这是一个函数,用于计算此类的两个实例的“按元素的最小值” 1

Homog min(const Homog& l, const Homog& r) {
  return {
      std::min(l.a, r.a),
      std::min(l.b, r.b),
      std::min(l.c, r.c),
  };
}

太好了。

现在,我要计算 max 而不是 min 。该代码是相同的,但是用std::min代替了std::max。我不想复制它,而是想使用一个通用的“按元素应用”方法,然后将min和max调用适当的函子:

Homog apply(const Homog& l, const Homog& r, ?? op) {
  return {
      op(l.a, r.a),
      op(l.b, r.b),
      op(l.c, r.c),
  };
}

Homog min(const Homog& l, const Homog& r) {
    return apply(l, r, std::min);
}

Homog max(const Homog& l, const Homog& r) {
    return apply(l, r, std::max);
}

当然,上面的代码不起作用,因为我不知道如何声明op。它不是普通的泛型仿函数对象,因为它需要处理不同的类型。

我可以做我想做的事情吗,以某种方式传递“为每个成员打电话给我:别担心,它将为每种类型分解成某种东西”的字眼?


在这里使用min()并不是最好的名称,因为它的行为与总是返回两个给定对象之一的std::min不同:此方法返回一个新对象,该对象在general与两个输入中的任何一个都不相同,而是它们的成员值的混合。

1 个答案:

答案 0 :(得分:2)

  

当然,上面的代码不起作用,因为我不知道如何声明op。它不是普通的泛型仿函数对象,因为它需要处理不同的类型。

通常使用带有模板operator()的功能来绕过此问题。

从C ++ 14(引入通用lambda)开始,如下所示

template <typename F>
Homog apply(const Homog& l, const Homog& r, F const & op) {
  return {
      op(l.a, r.a),
      op(l.b, r.b),
      op(l.c, r.c),
  };
}

Homog min(const Homog& l, const Homog& r) {
    return apply(l, r, [](auto const & a, auto const & b){ return std::min(a, b); });
}