2014-11-10 6 views
2

Я попытался написать «инлайн-вектор» класс для хранения количества элементов в стеке удобно:C++ элемент массива без инициализации

template<typename T, size_t size_ = 256> 
struct InlineVector{ 
    T content[size_]; 
    size_t num; 

    T() : num(0) {} 

    ~T() { for(size_t s = 0; s < num; s++){ content[s]->~T(); } } 

    template<typename _Up, typename... _Args> 
    void emplace_back(_Args&&... __args) { new (&content[num++]) T(__args); } 

    T& get(size_t i) { assert(i < num); return content[i]; } 


} 

соображений эффективности, я хочу, чтобы content не инициализируется в X , даже если T имеет только нетривиальный конструктор. Как вы видите, содержимое инсайтируется позже с размещением нового, когда оно фактически вставлено. Однако C++, похоже, требует, чтобы все элементы content были инициализированы при инициализации X. Например, это не компилируется:

struct Y{ Y(int){} } 

X<Y> foo; // compile error, no constructor for Y is called in the construction of X 

Итак, как можно иметь элемент массива, который не инициализирован, даже если тип элемента массива нужен конструктор?

ответ

6

Сделав массив массив char с последующим размещением new -в его. char - это единственный тип, с которым вам разрешено это делать.

Пока вы на него, то вы можете также написать свой собственный аллокатора вместо (с массивом в качестве одного из его членов), и вставьте его в std::vector, а не заново изобретать целую хижину.

std::vector<int, YourAllocatorType<int, 256>> v; 
+0

Интересная идея с распределителем. И спасибо за фактический ответ на использование массива 'char', поскольку распределитель будет иметь ту же проблему, что и вектор. Кажется, что нет никакого пути вокруг массива 'char', независимо от того, написана ли распределитель или вектор. – gexicide

+0

@gexicide: Да не очень :) –

1

Итак, как можно иметь элемент массива, который не инициализирован, даже если тип элемента массива нужен конструктор?

Это не для T x[n] ... но вы можете указать любые старые T* на выравнивать неиницализированные памяти, то управлять собственным одноранговым строительством и разрушением. Вы также можете изучить создание union с вашим типом и сказать char и иметь массив союзов ....

+0

Я не думаю, что «union» разрешен с членами с нетривиальными конструкторами. Но это не нужно; массив символов и литье прекрасны и до тех пор, пока один из типов «char», четко определен. –

+0

@JanHudec: существуют ограничения по типу, но я считаю, что они существенно расслабились для C++ 11 ... конечно, что-то, что нужно иметь в виду. У меня нет времени на то, чтобы точно разобраться в себе. –

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