Introduction
Peter Weinhart describes how to design a generic intrusive_ptr base class using CRTP, which may be used as follows:
class foo : intrusive_base<foo>
{
// foo-specific code.
};
This approach imposes the constraint that all foo
objects carry a reference counter. Assume that we keep foo
sometimes by value and only want to pay the price of the reference counter when we have a pointer. For example, sometimes we would like to create foo
instances and just move them around, and sometimes we want to allocate foo
on the heap.
Conceptually, the right mechanism for this scenario is a std::shared_ptr
. However, there are certain scenarios requiring raw pointers that would call for an intrusive pointer, e.g., when passing pointers through a C API that take void pointers. In this case, one would "ref" the pointer before passing it to the opaque API and "unref" when getting it back.
Having control over foo
, probably the best method would be to use a policy-based implementation and have a reference-counted and basic version of foo
. Without having control over foo
, an alternative design would to invert the inheritance relationship:
template <typename Base>
class intrusive : public Base
{
// ?
private:
std::atomic_size_t ref_count_;
};
typedef intrusive<foo> intrusive_foo;
// Assume boost::intrusive_ptr as intrusive pointer implementation
boost::intrusive_ptr<intrusive_foo> x = new intrusive_foo;
{
auto y = x; // Semantics: boost::intrusive_ptr_add_ref(x.get())
// At scope exit: boost::intrusive_ptr_release(x.get())
}
In the above mentioned article, Peter says that a such a "generic implementation of [intrusive
] would make use of C++0x variadic templates and perfect forwarding."
Question
How would the implementation of such a generic intrusive
class look like? I could see that it may benefit from C++11 inheriting constructors, but it is unclear to me how one would in fact implement the body of intrusive
using the mentioned tools.