2016-10-17 40 views
5

我正在實現一些非常類似於std::vector的東西,但在堆棧上使用數組而不是內存分配。sfinae走了一個析構函數

d-tor調用一個使用SFINAE的函數。

  • 如果value_type是POD功能有空體。
  • 如果value_type是普通類std::string,則該函數具有正文並正確銷燬所有數據。

現在,我希望能夠使用這個新的std::vector作爲constexpr。然而即使C-tor被宣佈爲constexpr,代碼也不編譯,因爲這個類有非平凡的d-tor。

下面是代碼的一小部分:

template<typename T, std::size_t SIZE> 
class SmallVector{ 
    constexpr SmallVector() = default; 

    ~SmallVector(){ 
     destructAll_<value_type>(); 
    } 

    // ... 

    template<typename X> 
    typename std::enable_if<std::is_trivially_destructible<X>::value == true>::type 
    destructAll_() noexcept{ 
    } 

}; 

有什麼我可以做,使類是constexpr如果value_type是POD和非POD數據類型保持功能。
(當然不是)

+2

我反而從'SmallVectorImpl ::值>'這將有一個主要定義和平凡破壞類型的特化繼承。兩者之間的唯一區別是析構函數。 – DeiDei

+0

我的想法很相似 - 一個只讀基類和兩個繼承版本中的所有變異方法。 您是否也可以對您的想法做出回答,因爲我沒有看到第三個模板「組件」如何提供幫助。你的意思是繼承兩個基類嗎? – Nick

+0

與'std :: vector'類似的類型可以這樣嗎?你是不是重新實現'std :: array'? Orrrr是一個擁有巨大自動存儲陣列和大量新位置的矢量嗎? :) –

回答

5

不幸的是,沒有辦法啓用/禁用SFINAE的析構函數,也沒有辦法與未來的概念。這是因爲destructos:

  • 無法模板
  • 不能有參數
  • 不能有返回類型

你可以做的是專注全班或更好的是,創建一個只包含構造/破壞和基本訪問的基類,並將其專門化。

template <class T, class Enable = void> 
struct X { 
    ~X() {} 
}; 

template <class T> 
struct X<T, std::enable_if_t<std::is_pod<T>::value>> { 
}; 

static_assert(std::is_trivially_destructible<X<int>>::value); 
static_assert(!std::is_trivially_destructible<X<std::vector<int>>>::value);