STL使用“小于”作为默认比较器。 STL比较器调用用reference_wrapper<>包裹的对象。 does not compile,即使基础类具有“<”运营商定义。
看来,这是因为当它是一个成员函数时, LHS.operator<(RHS)的 LHS 上执行了no implicit conversion 。我已经验证了using a free version作为比较器的工作原理。
但是,如果reference_wrapper提供了“<”运算符,调用“<”在底层,将使用免费功能的需要将被避免。
我在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&lt;&gt;提供与许多库所需的ptrs相关联的复制/分配语义,同时隐藏与ptr相关的语法。这允许使用引用类型语法,而不需要本地副本的开销。要将它与使用ptrs的示例进行比较,完全错过了reference_wrappers的 一个 :您希望避免使用ptr类型语法。 < / p>
现在的情况就是,当对象被包装在reference_wrappers中时,直接处理对象的代码会中断。不用说,“&lt;”作为默认比较器,确实使它变得特别;在很大比例的现有代码中,对象将定义这些代码以避免需要特殊的比较器。
后来添加#2: 此功能的历史表明,避免使用ptr语法并不是最初的意图。然而,自推出首次推出以来已经过去了十年。由于大量新程序员“被引导”to avoid ptr based syntax(毫无疑问受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
答案 0 :(得分:9)
不,不应该。执行任何操作都不是reference_wrapper
的工作,而是将引用包装为值。
如果你需要比较两个reference_wrapper<T>
(不对T
的引用),那么你的工作就是完成它。出于同样的原因,std::set<T*>
并不默认将比较定义为std::less<T>(*x, *y)
,您的情况也不应如此。包装器只是一个非空指针。
为什么要停在单个比较运算符或所有比较运算符?为什么不重载所有标准函数的参考包装器?因为当解决方案如此简单时,它是不值得的。