为什么没有bool std :: operator ==(T1 * a,std :: shared_ptr <t2> b)的重载?</t2>

时间:2014-05-06 21:13:33

标签: c++ c++11 operator-overloading shared-ptr

我注意到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();
}

......这种实施有什么危险或意外吗?

2 个答案:

答案 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::lessshared?) - 天真地,你可能会说不,但如果你unique不必代表内存所有权替换删除者! (unique_ptr也是如此)。是否应将具有不同删除者的智能指针视为相同或等效?基于删除者,数据的含义可能会有很大差异。

现在,鉴于我已经设法从几分钟的工作中提出了棘手的问题,这样的重载会鼓励混合原始指针和shared_ptr它甚至无法解决您想要解决的问题,也许这不是一个好主意。

或者也许是。这导致了它不符合标准的真正原因。

没有人提出并接受它。

如果您认为这是一个好主意,我建议您查看提案流程。检查其他提案,找出正确的步骤,并一起提出提案。

如果这看起来太吓人了,你可能想要创建一个强大的库来提供所谓的比较运算符,并让它进入提升,并且可能人们会使用它并说“哇,我们总是需要它!”