Boost logo

Boost Users :

Subject: Re: [Boost-users] Incomplete types and intrusive_ptr
From: Dominique Devienne (ddevienne_at_[hidden])
Date: 2009-05-12 17:59:22

On Tue, May 12, 2009 at 3:11 PM, Peter Dimov <pdimov_at_[hidden]> wrote:
> Dominique Devienne:
>> Is it possible to achieve the ability of shared_ptr<T> to be used as a
>> class member in a class declaration with an incomplete type T, with
>> intrusive_ptr?
> The usual approach is to declare:
>   class X;
>   void intrusive_ptr_add_ref( X* );
>   void intrusive_ptr_release( X* );

Thanks Peter. This helped me see that I need a declaration of the
add_ref/release functions *per* derived class T of RefCountedBase,
that I want to fwd declare to avoid including its header.

Previously I just declared add_ref/release for RefCountedBase, and
since the derivation is not know by just fwd decl SomeRefCounted, I
was getting this error:

error C2664: 'boost::intrusive_ptr_release' : cannot convert parameter
1 from 'acme::SomeRefCounted *' to 'acme::RefCountedBase *'

and wrongly assumed intrusive_ptr<T> required a complete T. I've
summarized the issue I was having below. Thanks again for your help.
Regards, --DD

// in refcountedbase.h
namespace acme {
    class RefCountedBase {
        void ref() { ++refcount_; }
        void unref() { if (--refcount_ == 0) { cleanup(); delete this; } }

        static void ref(RefCountedBase* r) { if (r) r->ref(); }
        static void unref(RefCountedBase* r) { if (r) r->unref(); }

        RefCountedBase() : refcount_(0) {}
        RefCountedBase(const RefCountedBase&) : refcount_(0) {}
        virtual ~RefCountedBase() {}

        virtual void cleanup() {}

        RefCountedBase& operator=(const RefCountedBase&);

        int refcount_;

// in acme/intrusive_ptr.h
#include <boost/intrusive_ptr.hpp>
namespace acme {
    using boost::intrusive_ptr;
    inline void intrusive_ptr_add_ref(acme::RefCountedBase* r) {
    inline void intrusive_ptr_release(acme::RefCountedBase* r) {

// in acme/foobar.h
// #include <acme/intrusive_ptr.h>
namespace acme {
    class SomeRefCounted;
    void intrusive_ptr_add_ref(SomeRefCounted* r);
    void intrusive_ptr_release(SomeRefCounted* r);

    class FooBar {
        intrusive_ptr<SomeRefCounted> some_; // WAS GETTING COMPILE ERROR HERE

// in acme/somerefcounted.h
// lots of #include
namespace acme {
    class SomeRefCounted : public RefCountedBase {};

    inline void intrusive_ptr_add_ref(SomeRefCounted* r) {
    inline void intrusive_ptr_release(SomeRefCounted* r) {

void intrusive_ptr(int /*argc*/, const char* /*argv*/[]) {
    using namespace acme;
    FooBar foobar;

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at