假设我有一个由同类类型组成的类:
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与两个输入中的任何一个都不相同,而是它们的成员值的混合。
答案 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); });
}