I've written what I would hoped to be a general purpose CRTP class that allows my own classes to easily extend a class that implements a shared_from_this
function (presumably returning a shared pointer equivalent to this), giving direct access to the shared pointer for the derived class instead of the base, as follows:
template<class Self, class Super>
class inherit_shared_from_this : public Super {
public:
std::shared_ptr<const Self> shared_from_this() const {
return std::static_pointer_cast<const Self>(Super::shared_from_this());
}
std::shared_ptr<Self> shared_from_this() {
return std::static_pointer_cast<Self>(Super::shared_from_this());
}
};
This works quite well for single inheritance trees, but I was wanting to extend it to be able to inherit from more than one class that implements shared_from_this
. When I do so, however, I get an error 'shared_from_this' is ambiguous, because the compiler can't tell which exact class I am meaning to inherit the shared_from_this
function. In fact, it does not matter which one.
What I wanted to do is define a class as follows:
class Foo : public inherit_shared_from_this<Foo, A, B, C> {
...
};
Where all of A, B, C, and D implement a shared_from_this
function, and this class will publicly inherit from each of the classes other than the first, and implement exactly two shared_from_this
methods, for both const and non-const versions, to return the applicable shared_pointer version of this
(in this case, std::shared_ptr<Foo>
).
The first thing I tried to do was adding a variadic definition for the class as follows:
template<class Self, class Super, typename... Args>
class inherit_shared_from_this : public Super, public inherit_shared_from_this<Self, Args...> {
public:
std::shared_ptr<const Self> shared_from_this() const {
return std::static_pointer_cast<const Self>(Super::shared_from_this());
}
std::shared_ptr<Self> shared_from_this() {
return std::static_pointer_cast<Self>(Super::shared_from_this());
}
};
That did not work, however... it objected that the two definitions of inherit_shared_from_this
had different numbers of parameters.
Any ideas on how I can do what I am trying to accomplish, or is it just not possible?
EDIT:
A clarification on why std::shared_from_this
is not usable as-is:
If I simply inherit directly from the class that inherited std::enable_shared_from_this
in a derived class that also inherits from something that inherited from std::enable_shared_from_this
, then it returns the wrong pointer type. If I use multiple inheritance and also inherit from std::enable_shared_from_this
in a derived class whose base had extended std::enable_shared_from_this
, then calling shared_from_this()
in the derived class is ambiguous. Therefore a class that can inherit from such classes is required if access to the derived pointer is wanted.
EDIT: This question differs from mine in that I am wanting to avoid adding virtual inheritance into things unless it is explicitly asked for. Since std::enable_shared_from_this itself does not have a virtual destructor in the first place, it seems improper to add that cost to what I am trying to design as a general purpose class whose purpose is to be just as reusable.