[2021.8.28][6 函数子类及函数] 42. 确保less<T>与operator<具有相同的语义(POLA)
假设Widget包含一个重量值和一个最大速度值:
class Widget {
public:...size_t weight() const;size_t maxSpeed() const;...
};
通常情况下,按重量对Widget排序是最自然的方式:
bool operator<(const Widget& lhs, const Widget& rhs)
{return lhs.weight() < rhs.weight();
}
假如我们需要创建一个按照最大速度进行排序的multiset
// 这是std::less对Widget的特化版本;一种不好的做法
template<>
struct std::less : public std::binary_function {bool operator()(const Widget& lhs, const Widget& rhs) const{return lhs.maxSpeed() < rhs.maxSpeed();}
};
作为一般性规则,对std名字空间的组件进行修改通常是禁止的,会导致未定义的行为。但在某些特定情况下,对std名字空间的修补工作仍然是允许的,特别是,针对用户定义的类型,特化std中的模板。下面的例子就是Boost库的智能指针shared_ptr的部分实现:
namespace std {// 针对boost::shared_ptr的std::less特化templatestruct less> : public binary_function, boost::shared_ptr, bool> {bool operator()(const boost::shared_ptr& a, const boost::shared_ptr& b) const {// shared_ptr::get返回shared_ptr对象的内置指针return less()(a.get(), b.get());}};
}
这没有什么不合理,上面的less特化只是确保智能指针的排序行为与它们的内置指针的排序行为一致。
让less不调用operator<而去做别的事情,这会无端地违背程序员的意愿,违背了最小惊讶原则POLA(the principle of least astonishment)。
回到那个按照最大速度对multiset
struct MaxSpeedCompare: public binary_function {bool operator()(const Widget& lhs, const Widget& rhs) const{return lhs.maxSpeed() < rhs.maxSpeed();}
};
我们使用MaxSpeedCompare作为比较类型来创建我们的multiset:
multiset widgets;
总结:
应该尽量避免修改less的行为,因为这样做很可能会误导其他的程序员,违背POLA程序设计原则。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
