【问题标题】:How to reference self type in default template arguments?如何在默认模板参数中引用自我类型?
【发布时间】:2017-03-27 11:50: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);
        }
   }
}

我理解这个错误。 那么问题来了,如何在模板默认参数中引用当前的类类型或者其他方式来实现这个设计模式呢?

【问题讨论】:

    标签: c++ c++11 templates standards c++-standard-library


    【解决方案1】:

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

    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 on wandbox

    【讨论】:

      【解决方案2】:
      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);
          }
        }
      };
      

      【讨论】:

        猜你喜欢
        • 2020-01-09
        • 2014-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多