I have implemented a swap method for my class that inherits from enable_shared_from_this<...>
class X : public enable_shared_from_this<X> {
int x;
friend void swap(X& x1, X& x2) {
using std::swap;
swap(x1.x, x2.x);
}
X& operator=(X other) {
swap(*this, other);
}
...
}
I tried to swap the enable_shared_from_this<...> part in the swap method by adding either:
std::enable_shared_from_this<X>::swap(first, second);
Doesn't compile because of:
No member named 'swap' in 'std::enable_shared_from_this'
swap(static_cast<std::enable_shared_from_this<X>>(first), static_cast<std::enable_shared_from_this<X>>(second));
Doesn't compile because of:
Calling a protected constructor of class 'std::enable_shared_from_this' protected constructor can only be used to construct a base class subobject
Finally I resorted to adding the following line in the assignment operator:
std::enable_shared_from_this<X>::operator=(other);
But this feels wrong to me because the swap method is incomplete and in general mixing two idioms (I guess).
So what is the correct way to handle this...?
Note: I'm using C++20.
enable_shared_from_thistechnically has a copy constructor and assignment operator. But they don't meaningfully work. Neither of them copies theweak_thisinternal member. So even after assignment, theweak_thiswill be the same.Swapping is not functionality that
enable_shared_from_thissupports.Note that swapping them wouldn't actually make sense. The
shared_ptrs managing the memory for each object point to the specific objects they manage. Swapping objects only swaps their contents; the address of the two objects remains the same. So the managed storage should still refer to the original objects because their addresses didn't change.As such, it makes sense that you cannot "copy" or "swap"
enable_shared_from_this. So just leave the base class subobjects alone.