Home > OS >  Question about operator==( const std::shared_ptr& lhs, const std::shared_ptr& rhs )
Question about operator==( const std::shared_ptr& lhs, const std::shared_ptr& rhs )

Time:05-15

As per the document, which says that:

template < class T, class U > 
bool operator==( const
std::shared_ptr<T>& lhs, const std::shared_ptr<U>& rhs ) noexcept;

It indicates lhs and rhs could be different types. What surprises me is that the code snippet below does not compile. I fully understand what the compiler complains. What confuses me is the said document says the lhs and rhs could be different types.

Here is the said code snippet:

#include<memory>
#include<vector>
#include<iostream>

struct Widget
{
    std::vector<int> vec;
    int var;
};

int main()
{
    auto wp{std::make_shared<Widget>(std::vector<int>{1,2,3}, 69)};

    std::shared_ptr<std::vector<int>> vp{wp, &wp->vec};

    std::cout << wp.owner_before(vp) << std::endl;
    std::cout << vp.owner_before(wp) << std::endl;

    std::cout << (wp==vp) << std::endl;
}

CodePudding user response:

They can be different types, but they must be comparable. A Widget* and a std::vector<int>* doesn't have an operator== overload and neither is convertible to the other.

Note that the comparison operators for shared_ptr simply compare pointer values; the actual objects pointed to are not compared.

Here's an example where comparing different types would work:

#include<memory>
#include<iostream>

struct foo {};
struct bar : foo{};

int main()
{
    auto f = std::make_shared<foo>();
    auto b = std::make_shared<bar>();

    std::cout << (f == b) << std::endl;
}

CodePudding user response:

From std::shared_ptr's operator_cmp:

Note that the comparison operators for shared_ptr simply compare pointer values; the actual objects pointed to are not compared.

Note the highlighted part in the above quoted statement which means that the pointer objects that is handled by the respective shared_ptr are compared. And in your example, the pointer objects handled by the respective share_ptr are Widget* and std::vector<int>* which are compared. But since there isn't an overloaded operator== that compares a Widget* with a std::vector<int>*, the program fails to compile.


For example, if you derive a Button from the Widget and then compare shared_ptr<Widget> and shared_ptr<Button> the program will work.

Demo.

  • Related