如何在默认模板参数中引用 self 类型

How to reference self type in default template arguments?

本文关键字:引用 self 类型 参数 默认      更新时间:2023-10-16

我们有一个reference_counted模板和一个默认的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;
        }
   }
}

我们要为 reference_counted 类添加分配器。但是我们不知道如何编写默认模板参数,因为编译器会抱怨递归类型引用。

//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);
        }
   }
}

我理解这个错误。所以问题是如何在模板默认参数中引用当前类类型或其他实现此设计模式的方法?

您可以使用更高种类的类型("模板模板参数"(

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);
   }
};

魔杖盒上的现场示例

template <class T, class D_in = void>
class reference_counted: T
{
public:
  using D = std::conditional_t<
    std::is_same_v<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);
    }
  }
};