[C ++ 11 STL中是否有适当的方法将对象指针存储在std::set
中,并通过对象的operator <
方法对其进行正确排序?
当然,有可能编写我自己的Compare
类型并将其作为第二个模板参数传递给set
,但我想STL将提供一种更为方便的方法。
有些搜索显示std::reference_wrapper
,我认为应允许这样的代码:
#include <functional>
#include <set>
struct T {
int val;
bool operator <(T& other) {
return (this->val < other.val);
}
};
int main() {
std::set<std::reference_wrapper<T>> s;
T a{5};
s.insert(a);
}
但是实际上,这会导致编译器错误:
clang++ -std=c++11 -Wall -Wextra -pedantic test.cpp -o test
In file included from test.cpp:1:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/functional:49:
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/bits/stl_function.h:235:20: error: invalid operands to binary expression ('const std::reference_wrapper<T>'
and 'const std::reference_wrapper<T>')
{ return __x < __y; }
~~~ ^ ~~~
(gcc错误与之类似,但时间更长)
您需要使小于运算符成为非成员,并为其提供const
参考参数:
struct T {
int val;
};
bool operator <(const T& lhs, const T& rhs) {
return (lhs.val < rhs.val);
}
这允许在std::reference_wrapper<T>
运算符的LHS和RHS上从T
到<
进行隐式转换,而成员版本仅允许在RHS上进行隐式转换。二进制运算符的LHS和RHS之间的对称性是将其实现为非成员的经典论据之一。
无法对调用方法的对象进行隐式转换,因此您需要将比较实现为自由函数,以使用从reference_wrapper
正确的方法是为我们的MyStruct创建专门的std::less
。>>
namespace std { template<> struct less<MyStruct> { bool operator() (const MyStruct& lhs, const MyStruct& rhs) const { return lhs.a < rhs.a; } }; }
记住
std::set
默认使用std::less
比较两个元素。
在标题<set>
中定义
template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class set;