STL 使用“小于”作为默认比较器。即使基础类定义了“<”运算符,对使用 reference_wrapper<> 包装的对象的 STL 比较器调用也不会编译。
看来,这是因为当LHS.operator<(RHS)是成员函数时,没有在LHS上执行隐式转换。我已经验证了使用免费版本作为比较器的工作原理。
但是,如果 reference_wrapper 提供了“<”运算符,它在底层调用“<”,则无需使用 free 函数。
我在 reference_wrapper 的代码中添加了以下内容(取自 VS11 Beta xrefwrap.h),并且可以将 std::map 与包装在我的 reference_wrapper<> 版本中的类一起使用,该版本定义了“<”运算符。
bool operator <(reference_wrapper<_Ty> const rhs) const {
return this->get() < rhs.get();
}
稍后添加:如果我理解正确,reference_wrapper<> 提供了与许多库所需的 ptr 相关的复制/分配语义,同时隐藏了与 ptr 相关的语法。这允许使用引用类型语法,而没有本地副本的开销。将它与使用 ptrs 的示例进行比较完全错过了 reference_wrappers 的要点之一:您要避免使用 ptr 类型语法。
现在的情况是,直接作用于对象的代码在对象被包装在 reference_wrappers 中时会中断。不用说,“<”是默认的比较器,确实使它特别;在现有代码的很大一部分中,对象将定义这些以消除对特殊比较器的需要。
稍后添加 #2:此功能的历史表明,避免使用 ptr 语法并不是最初的意图。然而,自从它首次在 boost 中引入以来已经有十年了。随着大量新程序员“指导”避免使用基于 ptr 的语法(无疑受到 ptr 自由语言的影响),如果它可以更无缝地工作,特别是在处理在 STL 容器中存储对象的遗留代码时,此功能将变得越来越有用,并且价值复制遍地。
稍后添加 #3:以最少的代码更改改进遗留代码 随着时间的推移,瘦类变得繁重,容器中对象的大小增加。提高性能的一种快速方法是通过包装对象避免复制。这将提供“C ptr”类型的性能,而无需对代码进行最小更改的额外副本。
std::map<const Object, string> objTable;
// can be rewritten as to avoid object copies using the
// __myOwn::reference_wrapper which contains the '<' operator
std::map<__myOwn::reference_wrapper<const Object>, string> rwTable_myOwn;
// which works with out any non-member free comparator functions
rwTable_myOwn[a]="One"; // Compiles and works
// When using the table with the std::reference_wrapper
std::map<std::reference_wrapper<const Object>, string> rwTable_std;
//the map does not work
rwTable_std[a]="One"; // Fails to compile it needs the custom non-member comparator