2017-03-02 47 views
4

我想打一個別名模板std::unique_ptr供應我自己刪除器功能。我怎樣才能使性病的有效C++模板別名::的unique_ptr

unique_ptr既有標量和數組實現,他們是這樣定義的:

template <class T, class D = default_delete<T>> 
class unique_ptr // scalar 

template <class T, class D> 
class unique_ptr<T[], D> // array 

我遇到麻煩試圖同時重寫的unique_ptr的標量和數組版本。這很容易使一個別名只有一個版本,像這樣:

template<class T> 
struct Deleter { 
    void operator()(T* ptr) { delete ptr; } 
}; 

template<class T> 
using my_unique_ptr = std::unique_ptr<T Deleter<T>>; 

但是當我嘗試添加第二個別名,就像這樣:

template<class T> 
struct ArrayDeleter { 
    void operator()(T* ptr) { delete [] ptr; } 
}; 
template<class T> 
using my_unique_ptr = std::unique_ptr<T[], ArrayDeleter<T>>; 

...我結束了編譯器錯誤因爲「my_unique_ptr」是不明確的。

我的問題是:如何創建一個可以同時用於陣列和標量版本unique_ptr的單個別名?

回答

4

你似乎是試圖專注一個using聲明。你不可以。

template<class T> 
struct my_unique_ptr_helper { 
    using type = std::unique_ptr<T, Deleter<T>>; 
}; 
template<class T> 
struct my_unique_ptr_helper<T[]> { 
    using type = std::unique_ptr<T[], ArrayDeleter<T>>; 
}; 

template<class T> 
using my_unique_ptr = typename my_unique_ptr_helper<T>::type; 

現在這有缺點,因爲它阻止扣除相當完全。

我們可以在其他地方移動的專業化解決這個問題。

template<class T> 
struct Deleter { 
    void operator()(T* ptr) const { 
    delete ptr; 
    } 
}; 
template<class T> 
struct ArrayDeleter { 
    void operator()(T* ptr) const { 
    delete[] ptr; 
    } 
}; 
template<class T> 
struct Deleter<T[]>:ArrayDeleter<T> {}; // inheritance 

現在:

template<class T> 
using my_unique_ptr = std::unique_ptr<T, Deleter<T>>; 

比較簡單,而且可以允許的T更演繹。

當然,這是毫無意義的,但我認爲你的真實Deleter是不一樣的std::default_delete

+0

這爲我工作,謝謝。我根本不需要製作ArrayDeleter結構。相反,我創建了一個通用的「模板刪除器」以及用於T []的Deleter專用化。 –

2

您應該向我們展示您的ArrayDeleter但是...您確定無法通過獨特的usingstd::conditional解決您的問題嗎?

我的意思是,像

template <typename T> 
using my_unique_ptr = std::unique_ptr<T, 
     typename std::conditional<std::is_array<T>::value, 
            ArrayDeleter<T>, 
            Deleter<T>>::type>; 

---編輯---

的OP說

我編輯的問題,包括ArrayDeleter上實施的實例

不知道(我做了很多錯誤的與模板陣列特),但我想應該工作,如果你可以修改ArrayDeleter如下

template <typename> 
struct ArrayDeleter; 

template <typename T> 
struct ArrayDeleter<T[]> 
{ void operator()(T* ptr) { delete [] ptr; } }; 
+0

我編輯了這個問題來包含一個示例ArrayDeleter實現。 –

+0

@DominicDosSantos - 回答改進;希望這可以幫助 – max66