2014-01-03 3 views
3

Есть ли способ сделать это:Могу ли я иметь переменный вектор в C++?

std::vector<char[foo]> bar; 

мне нужен один непрерывный массив char[foo], но я не знаю, длина до выполнения. Мне нужно иметь возможность добавлять блоки из char[foo] динамически.

мне нужен внутренний массив, чтобы быть точно правильный размер, так что если foo было 3:

[[1, 2, 3] [4, 5, 6] ... [х, у, г ]]

Я мог бы реализовать его сам, но не хочу изобретать велосипед.

+6

'std :: vector >'? –

+1

@ KirilKirov пытается это сейчас .. похоже, что он сработает. Сообщение ответ? – jsj

+0

@TonyD Если бы я знал значение foo во время компиляции – jsj

ответ

5

я предлагаю использовать

std::vector< std::vector<char> > 

std::vector «s внутренняя память непрерывно.


Ну, через некоторое время, оказалось, что вся память должна быть непрерывной, которая меняет все ..

В этом случае, вы можете использовать непосредственно std::vector<char>::insert(pos, begin, end) в insert целые «куски».

Что-то вроде: (я не проверял, но вы получите идею)

std::vector<char> bar; 
// .. 
{ 
    std::vector<char> buff(foo); 
    // fill buff 
    bar.insert(bar.end(), buff.begin(), buff.end()); 
} 

Только имейте в виду, что это может/будет вызывать перераспределение внутренней памяти и несколько копий элементов, но мы говорим о char, так что это не имеет большого значения.

Вы можете избежать этих перераспределений, используя std::vector::reserve, если у вас есть представление об окончательном размере bar.

+1

Спасибо за подсказку. Думаю, я собираюсь пойти с 'std :: vector >' хотя. Поскольку мне нужно, чтобы внутренние массивы были точно правильного размера. – jsj

+0

Лома, что .. Мне нужно все, чтобы быть смежным – jsj

+0

@ trideceth12 - см. Мое редактирование –

0

После того, как вопрос был перефразировать, вы, вероятно, ищете std::vector< std::array<char, 3> >

памяти будет непрерывным для всех элементов. Предполагая, что последнее уменьшение действительно является временем сборки const.

Пример:

std::vector< std::array<char, 3> > bar; 
std::array<char, 3> foo = { 'a', 'b', 'c' }; 
bar.insert(bar.end(), 10, foo); 
+0

Ahh Я вижу проблему .. Мне нужен внутренний массив, чтобы быть точно подходящим размером (недостаточно места, а затем некоторым) – jsj

+0

@ trideceth12 : Это может быть достигнуто с помощью '.reserve'. Поскольку вы не увеличиваете и не сокращаете свои векторы, недостатки не имеют отношения к вам. – MSalters

+0

@egur: Нет, вектор *> 'будет медленнее. Он имеет плохую локальность ссылок. – MSalters

-3

std::vector<char> bar(foo)

конструкты Foo символы с в векторе, а потому, что полукокс встроенного типа конструктор не будет называться так будет значение мусора, пока не инициализируются.

Вместо этого используйте std::vector<char> bar(foo, char()), чтобы заполнить его инициализированными символами.

+0

Это не ответ на вопрос. – MSalters

+3

На самом деле вы ошибаетесь (кроме того, что он вообще не отвечает на вопрос). 'std :: vector' * будет * инициализировать память с помощью' T() ', которая является * инициализацией значения * и равна нулю в памяти в случае встроенных модулей. –

3

Я бы сам создал контейнерный класс, используя внутри себя std::vector<char> и создаю оболочку slice, которая содержит указатель на класс контейнера и индекс в вектор. Класс контейнера будет содержать длину foo.Контейнер будет иметь итератор, возвращающий срезы, каждый slice будет иметь итератор, возвращающий char.

Это решение также выделяет непрерывную память.

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