2016-10-17 8 views
5

Я реализую что-то очень похожее на std::vector, но использует массив в стеке вместо распределения памяти.sfinae away the destructor

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

 Смежные вопросы

  • Нет связанных вопросов^_^