2017-03-27 7 views
3

我々は、次のよう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); 
     } 
    } 
} 

私はこのエラーを理解しています。 それでは、テンプレートのデフォルト引数などでこのクラスの型を参照してこのデザインパターンを実装する方法が問題になりますか?

答えて

2

あなたがより高いkindedタイプ( "テンプレートテンプレートパラメータ")使用することができます。

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

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