简体   繁体   English

C++ shared_ptr 相等运算符

[英]C++ shared_ptr equality operator

The equality operator for shared_ptr's is defined as follows: shared_ptr 的相等运算符定义如下:

template<class T, class U> inline bool operator==(
    shared_ptr<T> const & a, shared_ptr<U> const & b)
{
    return a.get() == b.get();
}

This seems broken.这似乎坏了。 Would it not have been better to forward the equality to what a and b are pointing to?将相等性转发给 a 和 b 指向的内容不是更好吗? Or would that be an unfair restriction on users of the library (in that they have to provide an equality operator)?或者这对图书馆的用户来说是一种不公平的限制(因为他们必须提供相等运算符)?

If I have a map or a hash_table containing shared_ptrs, then the current definition makes equality unusable.如果我有一个 map 或一个包含 shared_ptrs 的 hash_table,那么当前的定义使得相等性不可用。 For example, consider例如,考虑

std::map<int, std::tr1::shared_ptr<T> > m1, m2;

Won't we want to check that the ptrs for each int in m1 and m2 are pointing to the same value?我们不想检查 m1 和 m2 中每个 int 的指针是否指向相同的值吗?

I can implement my own equality by flattening m1, m2 out (constructing sets from each, dereferencing shared_ptrs along the way).我可以通过展平 m1、m2 来实现我自己的相等性(从每个构造集合,沿途取消引用 shared_ptrs)。 Is there an STL trick that will accomplish this or some other way to test equality in the presence of shared_ptrs neatly?是否有 STL 技巧可以完成这个或其他一些方法来巧妙地在存在 shared_ptr 的情况下测试相等性?

It's not broken, because a shared_ptr is conceptually a pointer, therefore it implements pointer-wise equality. 它没有被破坏,因为shared_ptr在概念上是一个指针,因此它实现了指针式的相等性。 When you test two pointers for equality, you want to know whether they point to the same place in memory. 当您测试两个指针是否相等时,您想知道它们是否指向内存中的相同位置。

I think the idea is that comparing two shared_ptr instances is about as useful as comparing two pointers. 我认为这个想法是比较两个shared_ptr实例和比较两个指针一样有用。 If you want a std::map containing shared_ptr s or plain old pointers to objects, you'll have to override the predicate with something that compares the pointed-to objects in either case. 如果你想要一个包含shared_ptrstd::map 或者指向对象的普通旧指针,你必须用比较两种情况下指向对象的东西来覆盖谓词。

In the case of comparing two maps, you would probably want to use the version of std::equal that takes a predicate. 在比较两个映射的情况下,您可能希望使用带有谓词的std::equal版本。

Just ran into a problem where I could use both types of equivalence. 刚遇到一个我可以使用两种类型的等价的问题。 An unordered set of shared_ptr where I wanted the equivalence to be based on the contents of the pointed to objects. 一组无序的shared_ptr,我希望等价基于指向对象的内容。 This can be implemented using a template specialization of hash and an overloaded ==. 这可以使用hash的模板特化和重载==来实现。 Now I have another container that also contains these pointers (an edge incidence list of sorts), but since we already know they are unique because we used the set, we can rely on pointer equivalence. 现在我有另一个容器也包含这些指针(一个边缘事件列表),但由于我们已经知道它们是唯一的,因为我们使用了集合,我们可以依赖指针等价。 Although the original equivalence would also work, it might be more efficient to just rely on the pointer equivalence in the second case -- this depends on the amount of data that are in the instances being compared. 虽然原始的等价也可以工作,但在第二种情况下依赖指针等价可能更有效 - 这取决于被比较实例中的数据量。

So, to answer the question. 所以,回答这个问题。 No it would not have been better, because how you use the flexibility provided depends on the problem being solved. 不,它不会更好,因为你如何使用提供的灵活性取决于正在解决的问题。

you can write your own subclass of std::shared_ptr with a operator== that does what you want.您可以使用operator==编写自己的std::shared_ptr子类来执行您想要的操作。 then the map can contain this objects那么 map 可以包含这个对象

template<class t>
class my_shared_ptr : public std::shared_ptr<t>
{
    bool operator==(const std::shared_ptr<t> &other)
    {
        return (*this->get()) == (*other.get());
    }
}

because the operator== isn't virtual, this will not work with pointers to shared_ptr 's因为operator==不是虚拟的,所以这不适用于指向shared_ptr的指针

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM