How to refer to type self in default template arguments?

We have a default template reference_counted

and class default_deallocator

:

template <class T>
class default_deallocator {
     void operator()(T* obj) {
         delete obj;
     }
};

template <class T>
class reference_counted: T
{
public:
   void retain() {ref_count++;}
   void release() {
        ref_count --;
        if (ref_count == 0) {
            delete this;
        }
   }
}

      

We want to add a deallocator for the class reference_counted

. But we don't know how to write the default template argument because the compiler will complain about a recursive type reference.

//VS2015 says: fatal error C1202: recursive type or function dependency context too complex
template <class T, class D = default_deallocator<reference_counted<T>>>  <---
class reference_counted: T
{
public:
   void retain() {ref_count++;}
   void release() {
        ref_count --;
        if (ref_count == 0) {
            D deallocator;
            deallocator.operator()(this);
        }
   }
}

      

I understand this error. So the question is how to refer to the current class type in the default template argument, or some other way to implement this design pattern?

+3


source to share


2 answers


You can use a higher type (template template parameter):

template <class T, template <typename...> class D = default_deallocator>  
class reference_counted: T
{
public:
   void retain() {}
   void release() {

        D<reference_counted<T, D>> deallocator;
        deallocator(this);

   }
};

      



live example in wandbox

+2


source


template <class T, class D_in = void>
class reference_counted: T
{
public:
  using D = std::conditional_t<
    std::is_same<D_in, void>,
    default_deallocator<reference_counted>,
    D_in
  >;
  void retain() {ref_count++;}
  void release() {
    ref_count --;
    if (ref_count == 0) {
        D deallocator;
        deallocator.operator()(this);
    }
  }
};

      



+1


source







All Articles