An answer recently posted on Stack Overflow显示的代码为标准算法提供了一个采用不同类型操作数的比较器:
2。使用带有模板化
operator()
的比较器。不使用lambda,而是定义带有模板
operator()
的算器。struct comparator { template<typename T, typename U> bool operator()(T const& lhs, U const& rhs) const { return lhs.mCommonField < rhs.mCommonField; } };
然后,它就像:
一样简单std::sort(aStructs.begin(), aStructs.end(), comparator{}); std::sort(bStructs.begin(), bStructs.end(), comparator{}); // ... std::set_intersection(aStructs.begin(), aStructs.end(), bStructs.begin(), bStructs.end(), std::back_inserter(intersection), comparator{} );
请注意,由于比较器中有模板,因此必须在函数范围之外声明。 Coliru Viewer上的实例。
显然,这至少可以在实践中发挥作用,工作现场演示证明了这一点。
但标准是否严格允许?
答案 0 :(得分:11)
标准中的相应部分是§25.4。 Compare
参数类型的唯一要求在§25.4/ 2中:
Compare
是一个函数对象类型。当上下文转换为Compare
时,应用于类型bool
的对象的函数调用操作的返回值,如果调用的第一个参数小于第二个,则产生true
,并且否则false
。假定有序关系的算法始终使用Compare comp
。假设comp
不会通过解除引用的迭代器应用任何非常量函数。
换句话说,在调用时,它不能更改迭代器指向的值,并且应该对值产生严格的弱排序。由于该比较器满足这两个要求,是的,这是合法的!
事实上,这种比较函子正是N3421 - Making Operator Functors greater<>
中提出的,现在是C ++ 14标准的一部分。它为标准库仿函数提供void
个特性,可以完美地与相应的运算符进行前向比较(如果有的话)。例如(摘自提案文件):
namespace std
{
template <> struct greater<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) > std::forward<U>(u))
{ return std::forward<T>(t) > std::forward<U>(u); }
};
}