Consider the following code:
struct Foo : std::enable_shared_from_this<Foo>
{
};
struct Bar
{
Foo foo;
};
int main()
{
std::shared_ptr<Bar> bar_p(new Bar);
//make shared_ptr to member with aliasing constructor
std::shared_ptr<Foo> foo_p(bar_p, &bar_p->foo);
assert(bar_p->foo.shared_from_this()); //fail! throws bad_weak_ptr
}
Unfortunately, it doesn't work as expected (at least in GCC 4.8.2). I looked into code and it seems that aliasing constructor simply doesn't call __enable_shared_from_this_helper()
which is necessary for proper work of shared_from_this()
.
Does anybody have any idea why it was designed in such a way? Is there something wrong with returning shared_ptr to member from shared_from_this?
[util.smartptr.shared.const]
foo_p
takes no ownership ofbar_p->foo
when you call the aliasing constructor, which in this case is a very good thing because otherwise it would try todelete
it on destruction.[util.smartptr.enab]
As
bar_p->foo
isn't owned by at least oneshared_ptr
you end up with undefined behavior, gcc throwsbad_weak_ptr
but it isn't obliged to do anything helpful.