В чем преимущество int[] перед vector<int> или array<int>

131
13 мая 2019, 23:50

Смотрю разный доступный код по C++ и много где массивы представляют в виде int p[3], например. Соответственно возник вопрос: это просто привычка из C/C# или действительно есть какая-то выгода с этого?

Answer 1

std::vector - это массив не только run-time начального размера, но еще и изменяемого на лету размера. Это заметно более "тяжелая" и дорогая структура данных, не являющаяся прямым аналогом обычного голого С-массива. Бездумно применять std::vector в качестве прямой замены обычного массива - плохая идея.

Что же касается std::array, то это прямой аналог С-массива, который к тому же является копируемым (в отличие от С-массива), т.е. передаваемым и возвращаемым по значению, присваиваемым и т.д. Свойство копируемости как раз и будет его основным преимуществом над голым С-массивом.

Также, std::array позволяет вам создавать массивы размера 0. В случае С-массивов такое возможно только при создании массива через new [].

Иногда в качестве преимущества std::array также называют унифицированность его интерфейса со стандартными контейнерами. Однако при необходимости такая унификация вполне достижима и для С-массивов, если алгоритмы реализуются в терминах функций std::begin, std::size и т.п.

В каких-то редких контекстах некопируемость голого массива и его манера превращаться в указатель могут быть полезными (например, при реализации <stdarg.h>), но такие контексты редки и экзотичны. В современном C++ коде, если вам нужен массив фиксированного размера, как правило нет никаких причин избегать использования std::array.

Разумеется отдельной темой будет совместимость с C-интерфейсами, где многие C++-структуры становятся неприменимыми. Но это само собой разумеется.

Answer 2

В большинстве случаев скорее в силу привычки, но иногда в этом есть смысл. Например, строковые константы определяются как

const char MyString[] = "My const string";

Не представляю себе человека, который в здравом уме взялся бы это делать через array<char>. Или, скажем опять же, константа

static const int arrInt[3] = { 1, 2, 3 };

выглядит проще и понятнее. Да и вообще константные массивы как-то странно делать классами, там просто нет нужды в возможностях класса.

Иногда и не для константы класс будет излишним и проще сделать традиционным массивом. Но это все надо смотреть для конкретного случая. А в общем случае, надо действительно стараться использовать контейнеры STL.

Answer 3

std::array<T, N> эквивалентен T[N] в большинстве случаев, и имеет лучший интерфейс. Но могут возникнуть сложности, если нужно совместить двумерный массив T[N][M] с двумерным std::array. По большему счету вариант T[N] используется или по привычке, или из-за меньшей многословности - полноценный интерфейс std::array нужен не всегда, а вариант T[N] явно короче, особенно в случае двумерных массивов. Также иногда компилятор генерирует разный код для этих вариантов, но нельзя сказать, какой из них лучше.

При передаче в качестве аргумента функции или в качестве возвращаемого значения std::array<T, N> по удобству выигрывает однозначно.

std::vector же является динамическим массивом, и его выбор обусловлен либо необходимостью динамического массива, либо нежеланием заморачиваться с вычислением размера времени компиляции. В частности, это может использоваться для реализации pimpl, когда для какого-то модуля количество элементов в возвращаемом значении известно во время компиляции, но не сообщается пользователям, чтобы при изменении реализации библиотеки не нужно было перекомпоновать её пользователей.

Answer 4

Есть у массива int p[3] одно неоспоримое преимущество - скорость создания.

Например, есть две функции:

void fun1(){
int p[3]= {1,2,3};
//some action
}
void fun2(){
std::vector<int> p= {1,2,3};
//some action
}

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

for(;;){
for(;;){
for(;;){
for(;;){
for(;;){
for(;;){
fun1();
//some action
}
}
}
}
}
}

Сравнение скорости создания массива фиксированного размера и массива динамического размера некорректно.

Как раз топик стартер спрашивает:

В чем преимущество int[] перед vector или array

Скорость создания массива фиксированного размера как раз и является преимуществом этого массива по сравнению с массивом динамического размера.

Ну и конечно ползать по динамическому массиву в общем случае медленнее, чем по массиву фиксированного размера. Можно даже померить на сколько медленнее, но это уж пусть сам топик стартер делает.

READ ALSO
Убрать помехи бинарное изображение C++

Убрать помехи бинарное изображение C++

Превращаю изображение в бинарное(черно-белое):

123
Двухпоточное приложение C++

Двухпоточное приложение C++

Всем привет, есть задача - Основной поток выделяет блок памяти размеров 200кб, заполняет его случайными числами и создает второй поток, который...

140
Поиск линии пикселей одного цвета C++

Поиск линии пикселей одного цвета C++

Есть изображения(ровная прямая линия может быть в любой стороны):

144
Ошибка: метод не определен в классе

Ошибка: метод не определен в классе

Есть два Java файла с одного пакетаПри при использование метода выдает ошибку "The method Print(String) is undefined for the type Hello"

157