intrusive_ptr icon indicating copy to clipboard operation
intrusive_ptr copied to clipboard

Relaxing constraints on complete types?

Open nlguillemot opened this issue 2 years ago • 1 comments

Right now the spec requires that T is a complete type, I feel like this is a tough requirement since neither shared_ptr nor unique_ptr have this requirement. Is there a way to work around the restrictions? The other pointer types have some specific places where completeness is required and other places where it's not. Maybe some detailed rules could be fleshed out here as well.

nlguillemot avatar Aug 16 '22 08:08 nlguillemot

Yes and no.

It is not possible to define intrusive_ptr<Foo> where Foo is incomplete. However, we do have a workaround for this:

GIven class Foo, we fabricate a complete type

class Foo_fwd : public intrusive_base<Foo_fwd>
  {
    virtual ~Foo_fwd();   // remember to define this elsewhere.
  };

intrusive_ptr<Foo_fwd> foo_ptr;  // valid, because `Foo_fwd` is complete.

But it its intrusive_ptr<Foo> that we would like. We have to make Foo and Foo_fwd convertible to each other:

class Foo : public Foo_fwd
  {
    virtual ~Foo();  // remember to define this elsewhere.
  };

int main()
  {
    foo_ptr.reset(new Foo);  // conversion from `Foo*` to `Foo_fwd*` is valid.
    auto other = static_pointer_cast<Foo>(foo_ptr);  // static_cast'ing from base to derived is also valid.
    asserrt(foo_ptr == other);
  }

We also have a templated solution here: https://github.com/lhmouse/asteria/blob/fc67e16552943b40acd834fb5101b0b2ab6a5c4f/src/fwd.hpp#L235 The helper function that performs base-to-derived conversion is called unerase_cast.

lhmouse avatar Aug 16 '22 08:08 lhmouse