标准算法比较器接受不同类型的对象是否合法?
Is it legal for a standard algorithm comparator to accept objects of different types?
最近在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.
显然,这至少在实践中是可行的,正如工作的实时演示所证明的那样。
但是标准严格允许吗?
标准中相应的章节是§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); }
};
}
相关文章:
- 是否需要删除包含对象的"pair"?
- 是否删除在对象构造过程中创建的对象
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 在这种情况下,java对象是否可以调用本机函数
- 返回指向对象的指针的函数调用是否为 prvalue?
- 具有引用成员的结构是否具有唯一的对象表示形式
- 对象初始化中是否允许指向此成员的指针?
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 堆分配的对象是否存在永不为空的唯一所有者?
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 是否可以使用一个类来控制 C++ 中另一个类的对象?(阿杜伊诺)
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- QFileSystemModel 对象是否会被删除?
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- 线程调用的函数对对象删除是否安全?
- 将对象的字节复制到数组并再次复制回来是否安全
- std::memmove在同一对象之间是否始终安全
- 类对象在 c++ 中是否具有数据类型?
- 是否可以将不可复制的成员用作使对象不可复制的替代方法?