В чем разница между std:: array и std::vector? Когда вы используете один над другим?

В чем разница между std::array и std::vector? Когда вы используете один над другим?

Я всегда использовал и рассматривал std:vector как С++-способ использования C-массивов, так в чем же разница?

Ответ 1

std::array - это просто версия класса классического массива C. Это означает, что его размер фиксируется во время компиляции, и он будет выделен в виде одного фрагмента (например, занимает место в стеке). Преимущество, которое у него есть, - это немного более высокая производительность, потому что между объектом и массивными данными нет никакой косвенности.

std::vector - это небольшой класс, содержащий указатели на кучу. (Поэтому, когда вы выделяете std::vector, он всегда вызывает new.) Они немного медленнее для доступа, потому что эти указатели нужно преследовать, чтобы добраться до массированных данных... Но взамен этого они могут быть изменены и они берут только тривиальное количество пространства стека независимо от того, насколько они велики.

[править]

Что касается того, когда использовать один над другим, честно говоря, std::vector почти всегда то, что вы хотите. Создание больших объектов в стеке обычно неодобрительно, и дополнительный уровень косвенности обычно не имеет значения. (Например, если вы перебираете все элементы, дополнительный доступ к памяти происходит только один раз в начале цикла.)

Элементы вектора гарантированно смежны, поэтому вы можете передать &vec[0] любой функции, ожидающей указателя на массив; например, подпрограммы библиотеки C. (В стороне, std::vector<char> buf(8192); - отличный способ выделить локальный буфер для вызовов read/write или подобных без прямого вызова new.)

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

Итак, мой совет: используйте std::vector, если (а) ваш профилировщик не говорит вам, что у вас есть проблема, и (b) массив мал.

Ответ 2

Я предполагаю, что вы знаете, что std:: array время компиляции фиксировано в размере, а std::vector - переменный размер. Кроме того, я предполагаю, что вы знаете, что std:: array не выполняет динамическое распределение. Поэтому вместо этого я отвечу, почему вы использовали бы std:: array вместо std::vector.

Вы когда-нибудь об этом делали:

std::vector<SomeType> vecName(10);

И тогда вы никогда не увеличиваете размер std::vector? Если это так, то std:: array - хорошая альтернатива.

Но действительно, std:: array (в сочетании с списками инициализаторов) существует, чтобы сделать массивы C-стиля почти совершенно бесполезными. Они обычно не конкурируют с std::vectors; они больше конкурируют с массивами C-стиля.

Подумайте об этом, поскольку комитет С++ делает все возможное, чтобы убить почти все законное использование массивов C-стиля.

Ответ 3

std::array

  • представляет собой совокупность
  • является фиксированным размером
  • требует, чтобы элементы по умолчанию конструктивны (vs copy (С++ 03) или переместить (С++ 0x) конструктивны)
  • линейно swappable (vs постоянное время)
  • является линейно подвижным (vs постоянное время)
  • потенциально платит одну менее косвенную, чем std::vector

Хорошим случаем использования является то, что он делает вещи "близко к металлу", сохраняя при этом тонкости С++ и сохраняя все плохие вещи из необработанных массивов.

Ответ 4

То же рассуждение при использовании массива Статический C-стиля, а не std::vector. И для этого я любезно отсылаю вас к здесь.

Ответ 5

std::array имеет фиксированное (время компиляции), а std::vector может расти.

Таким образом, std::array похож на использование массива C, а std::vector - как динамическое выделение памяти.

Ответ 6

Я использую свой собственный собственный код класса Array<>, который имеет более простой API по сравнению с std::array или std::vector. Например:

Чтобы использовать динамический массив:

Array<>  myDynamicArray; // Note array size is not given at compile time
myDynamicArray.resize(N); // N is a run time value

...

Чтобы использовать статический массив, фиксированный размер во время компиляции:

Array<100> myFixedArry;

Я считаю, что он имеет лучший синтаксис, чем std::array, или std::vector. Также чрезвычайно эффективен.

Ответ 7

Одно из преимуществ, которое векторы имеют над массивами, состоит в том, что можно найти текущий размер вектора, используя vector_name.size().

Как вы можете себе представить, это может быть очень полезно в самых разных ситуациях, где вы можете легко найти количество элементов в массиве.