最近发布在Stack Overflow上的答案显示了代码,它为标准算法提供了一个采用不同类型操作数的比较器:
2.使用带模板的比较器
operator().而不是使用lambda,定义一个带模板的仿函数
operator().Run Code Online (Sandbox Code Playgroud)struct comparator { template<typename T, typename U> bool operator()(T const& lhs, U const& rhs) const { return lhs.mCommonField < rhs.mCommonField; } };然后,它就像:
Run Code Online (Sandbox Code Playgroud)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上的实例.
显然,这至少在实践中有效,正如工作现场演示所证明的那样.
但标准是否严格允许?
tcl*_*amb 11
标准中的相应部分是§25.4.对Compare参数类型的唯一要求见§25.4/ 2:
Compare是一个函数对象类型.应用于类型对象的函数调用操作的返回值Compare,在上下文转换为时bool,将产生true调用的第一个参数是否小于第二个,false否则.Compare comp在整个过程中用于假设有序关系的算法.假设comp不会通过解除引用的迭代器应用任何非常量函数.
换句话说,在调用时,它不能更改迭代器指向的值,并且应该对值产生严格的弱排序.由于该比较器满足这两个要求,是的,这是合法的!
事实上,这种比较函子正是N3421中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); }
};
}
Run Code Online (Sandbox Code Playgroud)