SuperMurloc
SuperMurloc

Reputation: 209

No member named in class

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

Answers (1)

Revolver_Ocelot
Revolver_Ocelot

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

Related Questions