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.