类重载运算符 '<' 插入指向该对象集的共享指针时不调用
Class overloaded operator '<' is not called when inserting shared pointer to set of that objects
考虑以下程序:
#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:的文档
在内部,集合容器保持其所有元素的排序如下由其比较对象指定的标准。这些元素是始终按照此顺序插入其相应位置。
所以我希望每次插入都调用comparation对象。
比较对象默认为:
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类对象的?
正如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;
}
但这个解决方案清楚吗?这种改变默认值的明显工作方式会误导任何使用该容器的人吗?
相关文章:
- 如何从具有移动语义的类对象中生成共享指针
- 使用共享指针的函数调用,其对象应为 const
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 如何访问由共享指针保存的类方法?
- 从矢量或地图中删除共享指针
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- 使用共享指针实现复制 c'tor?
- 共享指针继承,而不先显式强制转换
- 如何检查类中共享指针的有效性?
- std::排序在共享指针的向量上
- 将相同共享指针的副本存储在不同的向量中是否是一种好的做法?
- 嵌套类、继承和C++中的共享指针
- 制作一对共享指针并推送一个向量
- 如何将共享指针用作函数参数
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 尝试通过共享指针使用变量时读取访问冲突
- 如何将元素插入到标准::地图的共享指针中?
- 共享指针生存期
- 初始化可变数据结构中的共享指针向量
- 阻止在返回时复制共享指针