我注意到stdlib没有为shared_ptr
和原始指针的等于运算符提供重载。如果你有一个std::unordered_set<std::shared_ptr<Foo>>
而你想要通过传递原始Foo*
有没有特殊原因没有这种超载?在我看来,它很容易实现:
template<typename T1, typename T2>
bool operator==(const T1 * a, const std::shared_ptr<T2> & b) {
return a == b.get();
}
......这种实施有什么危险或意外吗?
答案 0 :(得分:3)
如果你正在使用shared_ptr,传递原始指针是非常危险的,因为如果你有一些东西拿着那个原始指针,它按照定义会破坏shared_ptr引用计数的概念。没有过载的原因可能是阻止这种情况。
答案 1 :(得分:3)
对于unordered_set
,您需要的不仅仅是==
,还需要hash
才能工作。
对于set
,透明比较器可让您通过非关键类型的事物查找事物。 <{1}}默认情况下不透明,因此操作员不会有任何好处。
添加自己的比较器后,可以覆盖set
。
可悲的是,此时==
没有透明选项。要在unordered_set
中查找/删除/等某些内容,必须具有密钥类型。
你的超负荷是有问题的。更好的是:
unordered_set
但请注意,合理地编写上述内容需要C ++ 11支持。除上述内容之外的解决方案最终要么是乱写(使用SFINAE),要么声称类型之间存在template<class U, class...Ts>
auto operator==( U const* lhs, std::shared_ptr<Ts...> const& rhs )->decltype( lhs == rhs.get() ) {
return lhs == rhs.get();
}
template<class U, class...Ts>
auto operator==( std::shared_ptr<Ts...> const& lhs, U const* rhs )->decltype( lhs.get() == rhs ) {
return lhs.get() == rhs;
}
没有(并且其他SFINAE代码无法实现它太晚)。 / p>
但是==
呢?好吧,原始指针上的<
只是同一个对象中的一个好主意,因此在共享指针和原始指针之间公开它似乎是一个可怕的想法。所以现在我们正在接近<
,并希望通过智能指针和非智能指针之间的透明支持来增强它。
我们是否也支持混合智能指针(std::less
和shared
?) - 天真地,你可能会说不,但如果你unique
不必代表内存所有权替换删除者! (unique_ptr
也是如此)。是否应将具有不同删除者的智能指针视为相同或等效?基于删除者,数据的含义可能会有很大差异。
现在,鉴于我已经设法从几分钟的工作中提出了棘手的问题,和这样的重载会鼓励混合原始指针和shared_ptr
,和它甚至无法解决您想要解决的问题,也许这不是一个好主意。
或者也许是。这导致了它不符合标准的真正原因。
没有人提出并接受它。
如果您认为这是一个好主意,我建议您查看提案流程。检查其他提案,找出正确的步骤,并一起提出提案。
如果这看起来太吓人了,你可能想要创建一个强大的库来提供所谓的比较运算符,并让它进入提升,并且可能人们会使用它并说“哇,我们总是需要它!”