请考虑以下程序:
#include <string>
#include <iostream>
#include <set>
#include <memory>
class Boo
{
public:
using ShPtr = std::shared_ptr<Boo>;
bool operator < (const Boo& boo) const
{
std::cout << "Hello from operator";
return true;
}
};
int main(int, char*[])
{
std::set<std::shared_ptr<Boo>> _container;
_container.insert(Boo::ShPtr(new Boo()));
return 0;
}
根据std :: set:的文档
在内部,set容器将其所有元素排序如下 由其比较对象指定的条件。元素是 始终按照此顺序插入其各自的位置。
所以我希望每个插入对象都会调用比较对象。
默认情况下,比较对象是
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<_Key> >
class set
{
...
}
所以在这种特殊情况下是:
template<typename _Sp>
struct _Sp_less : public binary_function<_Sp, _Sp, bool>
{
bool
operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
{
typedef typename _Sp::element_type element_type;
return std::less<element_type*>()(__lhs.get(), __rhs.get());
}
};
通过比较共享指针指向的对象来完成比较。
我的问题是:为什么在我的程序运算符'<'中没有Boo类的对象?
答案 0 :(得分:0)
Richard Critten注意到:
@SombreroChicken“请注意,shared_ptr的比较运算符仅比较指针值;所指向的实际对象不进行比较。”来源:en.cppreference.com/w/cpp/memory/shared_ptr/operator_cmp因此它可以编译干净,但仅比较指针值
下面的代码按预期工作:
#include <string>
#include <iostream>
#include <set>
#include <memory>
template<typename _Sp>
struct CompShPtrByObj : std::_Sp_less<_Sp>
{
bool
operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
{
typedef typename _Sp::element_type element_type;
return std::less<element_type>()(*__lhs, *__rhs);
}
};
class Boo
{
public:
using ShPtr = std::shared_ptr<Boo>;
bool operator < (const Boo& boo) const
{
std::cout << "Hello form boo";
return true;
}
};
int main(int, char*[])
{
std::set<std::shared_ptr<Boo>, CompShPtrByObj<std::shared_ptr<Boo>>> _container;
Boo::ShPtr sharedBoo(new Boo());
Boo::ShPtr sharedBoo2(new Boo());
_container.insert(sharedBoo);
_container.insert(sharedBoo2);
std::set<std::shared_ptr<Boo>, CompShPtrByObj<std::shared_ptr<Boo>>>::iterator iter = _container.find(sharedBoo);
return 0;
}
但是这种解决方案清楚吗?那种改变默认值的明显工作方式是否会误导使用该容器的任何人?