1

I have a base class and child class. I want shared_from_this to return shared_ptr to the object in which it is invoked. So if shared_from_this() is called on child it should return a shared_ptr to child and same way for base. Below is my sample program

#include <iostream>
#include <memory>

class parent : private std::enable_shared_from_this<parent> {
public:
  int a;
  parent() : a(1) { }
  virtual void  f(){
    auto self = shared_from_this();
    std::cout << "Parent is " << self->a << std::endl;
  }
};

class child : public parent, private std::enable_shared_from_this<child> {
public:
  int a;
  child() : a (2) { }
  virtual void  f() {
    auto self = shared_from_this();
    std::cout << "Child is " << self->a << std::endl;
  }
};

int main(){
  auto p = std::make_shared<parent>();
  auto c = std::make_shared<child>();
  p->f();
  c->f();
}

Since enable_shared_from_this is privately inherited, shared_from_this() method for both the classes should be private to themselves hence there shouldn't be any collision/ambiguity. However I get following error while compiling.

[root@archlinux cpp]# clang++ -g stackoverflow_shared_from_this.cpp
stackoverflow_shared_from_this.cpp:19:17: error: member 'shared_from_this' found in multiple base classes of different types
    auto self = shared_from_this();
                ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0/bits/shared_ptr.h:807:7: note: member found by ambiguous name lookup
      shared_from_this()
      ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0/bits/shared_ptr.h:807:7: note: member found by ambiguous name lookup
1 error generated.
[root@archlinux cpp]#

Can somebody please explain why am I getting this ambiguity error ? What part of my explanation above is incorrect.

Evg
  • 25,259
  • 5
  • 41
  • 83
chandola
  • 126
  • 1
  • 10
  • 1
    Accessibility doesn't exclude a function from the overload resolution set, by language design. – Evg Jun 27 '21 at 06:12
  • 1
    The member functions inherited from `private` bases participate in overload resolution, just as they would with `public` or `protected` inheritance. There is ambiguity in your case, because two inherited bases have a `private` member function `shared_from_this()` with the same signature (no arguments). The check of `private` access only happens if an unambiguous match is found, which isn't true for your example. In any event, from C++17, `public` inheritance from `std::enable_shared_from_this` is mandatory. – Peter Jun 27 '21 at 06:12
  • If you get it to compile it won't work https://stackoverflow.com/questions/657155/how-to-enable-shared-from-this-of-both-parent-and-derived plus you need to publicly inherit from `enable_shared_from_this` or it won't work – Alan Birtles Jun 27 '21 at 06:13
  • Thanks a lot @Evg. I have got the reason for breakage. – chandola Jun 27 '21 at 06:21

0 Answers0