在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错误类似,但更长)
答案 0 :(得分:6)
您需要让您的less-than运算符成为非成员,并为其提供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之间的对称性是将它们作为非成员实现的经典论据之一。
答案 1 :(得分:2)
调用方法的对象不能被隐式转换,因此您需要将比较作为自由函数来实现,以使用来自reference_wrapper&lt; T&gt;的转换。到T。
答案 2 :(得分:0)
正确的方法是为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;