Если я хочу построить очень простой массив, например
int myArray[3] = {1,2,3};
Должен ли я использовать std::array
вместо этого?
std::array<int, 3> a = {{1, 2, 3}};
В чем преимущества использования std :: array перед обычными? Он более производительный? Просто проще обрабатывать копирование / доступ?
for (auto i = ++std::begin(myArray); . . .
может даже не компилироваться (кажется, что временные объекты фундаментального типа неизменяемы, по крайней мере, с clang 6)struct Direction { int32_t dw; int32_t dh; };
иstatic const Direction DIRECTIONS[DIRECTIONS_COUNT] { { -1, 1}, {0,1}, {1,1} , { 1, 0 }, {1,-1}, {0,-1} , {-1,-1}, {-1,0} };
компилируется. Но если вы перейдете кstd::array<Direction,DIRECTIONS_COUNT>
списку с тем же списком инициализаторов, вы неожиданно получите ошибку «слишком много инициализаторов». (Сообщество VS 2019 с языком = C ++ 17)std::array
инициализации?Ответы:
Он имеет дружественную семантику значения, так что его можно передавать или возвращать из функций по значению. Его интерфейс делает более удобным определение размера и использование с алгоритмами на основе итераторов в стиле STL.
Должно быть точно так же. По определению, это простой агрегат, единственным членом которого является массив.
Да.
источник
A
std::array
- очень тонкая оболочка для массива в стиле C, в основном определяемая какtemplate<typename T, size_t N> class array { public: T _data[N]; T& operator[](size_t); const T& operator[](size_t) const; // other member functions and typedefs };
Это агрегат , и он позволяет вам использовать его почти как основной тип (т.е. вы можете передавать по значению, назначать и т. Д., Тогда как стандартный массив C не может быть назначен или скопирован непосредственно в другой массив). Вам следует взглянуть на некоторую стандартную реализацию (перейти к определению из вашей любимой среды IDE или напрямую открыть
<array>
), это часть стандартной библиотеки C ++, которую довольно легко читать и понимать.источник
std::array
разработан как оболочка с нулевыми накладными расходами для массивов C, которая придает ему «нормальное» значение, подобное семантике других контейнеров C ++.Вы не должны замечать никакой разницы в производительности во время выполнения, пока все еще сможете пользоваться дополнительными функциями.
Использование
std::array
вместоint[]
массивов стилей - хорошая идея, если у вас есть C ++ 11 или boost.источник
Ситуация кажется более сложной, поскольку
std::array
не всегда получается идентичный ассемблерный код по сравнению с C-массивом в зависимости от конкретной платформы.Я тестировал эту конкретную ситуацию на Godbolt :
#include <array> void test(double* const C, const double* const A, const double* const B, const size_t size) { for (size_t i = 0; i < size; i++) { //double arr[2] = {0.e0};// std::array<double, 2> arr = {0.e0};//different to double arr[2] for some compiler for (size_t j = 0; j < size; j++) { arr[0] += A[i] * B[j]; arr[1] += A[j] * B[i]; } C[i] += arr[0]; C[i] += arr[1]; } }
GCC и Clang создают идентичный ассемблерный код как для версии C-массива, так и для
std::array
версии.Однако MSVC и ICPC создают разный код сборки для каждой версии массива. (Я тестировал ICPC19 с
-Ofast
и-Os
; MSVC-Ox
и-Os
)Я понятия не имею, почему это так (я действительно ожидал точно идентичного поведения std :: array и c-array). Возможно, используются разные стратегии оптимизации.
В качестве небольшого дополнения: похоже, что в ICPC есть ошибка с
#pragma simd
для векторизации при использовании c-массива в некоторых ситуациях (код c-array дает неверный результат;
std::array
версия работает нормально).К сожалению, у меня пока нет минимального рабочего примера для этого, так как я обнаружил эту проблему при оптимизации довольно сложного фрагмента кода.
Я отправлю отчет об ошибке в Intel, когда буду уверен, что я не просто неправильно понял что-то о C-array /
std::array
и#pragma simd
.источник
std::array
имеет семантику значений, а необработанные массивы - нет. Это означает, что вы можете скопироватьstd::array
и рассматривать его как примитивное значение. Вы можете получать их по значению или по ссылке как аргументы функции, а можете возвращать их по значению.Если вы никогда не копируете a
std::array
, то нет разницы в производительности по сравнению с необработанным массивом. Если вам все-std::array
таки нужно делать копии, то все будет правильно и все равно будет иметь такую же производительность.источник