Reputation: 209
So here's my code
MyClass.h:
namespace ns{
template <typename A, typename B>
class MyClass{
struct MyStruct1;
struct MyStruct2;
struct MyStruct1{
/*not important here*/
};
struct MyStruct2{
MyStruct2(std::weak_ptr<MyStruct1> i1, std::weak_ptr<MyStruct1> i2, B i3):d1{i1}, d2{i2}, d3{i3} {};
std::weak_ptr<MyStruct1> d1;
std::weak_ptr<MyStruct1> d2;
B d3;
};
//Compare MyStruct2
static bool compareMyStruct2(std::weak_ptr<MyStruct2>& e1, std::weak_ptr<MyStruct2>& e2);
};
template<typename A, typename B>
bool MyClass<A, B>::compareMyStruct2(std::weak_ptr<MyStruct2>& e1, std::weak_ptr<MyStruct2>& e2){
return (e1->d3 < e2->d3);
}
}
When I build, the compiler is telling me that
No member named 'd3' in 'std::_1::weak_ptr<ns::MyClass::MyStruct2'
I have no idea why. Any suggestions?
Upvotes: 3
Views: 2827
Reputation: 8783
Your problem is that you are trying to invoke operator->
on weak_ptr
, which does not have it.
weak_ptr
is not really a pointer-like object. It cannot be dereferenced. What you can do, is try to construct a shared_ptr
from it: if weak_ptr
has expired, you will get an exception, otherwise you will get valid shared_ptr
, which is a pointer-like object.
return (std::shared_ptr<MyStruct2>(e1)->d3 < std::shared_ptr<MyStruct2>(e2)->d3);
Easier way to do so is to call .lock()
on weak_ptr
:
return (e1.lock()->d3 < e2.lock()->d3);
But you must know that .lock()
returns empty shared_ptr
when called on expired weak_ptr
. You need to either test that resulting pointers are not equal to nullptr
, ensure that they did not expire beforehand or use shared_ptr
constructor from weak_ptr
.
Of course, if you need something more complex, you should store created shared_ptr
and not create it each time you want to access object:
auto p1 = e1.lock();
auto p2 = e2.lock();
if (not (p1 && p2))
throw /*expired pointers*/;
// Do stuff here
// return p1->d3 < p2->d3;
Upvotes: 2