Контейнер array из одноименного модуля <array>
представляет аналог массива. Он также имеет фиксированный размер.
Для создания объекта array в угловых скобках после названия типа необходимо передать его тип и размер:
#include <array> int main() { std::array<int, 5> numbers; // состоит из 5 чисел int }
В данном случае определен объект array из 5 чисел типа int. По умолчанию все элементы контейнера имеют неопределенные значения.
Чтобы инициализировать контейнер определенными значениями, можно использовать инициализатор - в фигурных скобках передать значения элементам контейнера:
std::array<int, 5> numbers {}; // состоит из 5 нулей
В данном случае пустой инициализатор инициализирует все элементы контейнера numbers нулями. Также можно указать конкретные значения для элементов:
std::array<int, 5> numbers {2, 3, 4, 5, 6};
Фиксированный размер накладывает ограничение на инициализацию: количество передаваемых контейнеру элементов не должно превышать его размер. Можно передать меньше значений, которые будут переданы первым элементам контейнера, а остальные элементы получат значения по умолчанию (например, для целочисленных типов это число 0):
std::array<int, 5> numbers {2, 3, 4}; // {2, 3, 4, 0, 0}
Однако если при инициализации мы предадим большее количество элементов, нежели размер контейнера, то мы столкнемся с ошибкой.
Стоит отметить, что начиная со стандарта C++17 при инициализации можно не указывать тип и количество элементов - компилятор выводит это автоматически исходя из списка инициализации:
std::array numbers {2, 3, 4, 5, 6};
Однако в этом случае в списке инициализации в фигурных скобках должно быть как минимум одно значение.
Для доступа к элементам контейнера array можно применять тот же синтаксис, что при работе с массивами - в квадратных скобках указывать индекс элемента, к которому идет обращение:
#include <array> #include <iostream> int main() { std::array<int, 5> numbers {2, 3, 4, 5, 6}; // получаем значение элемента int n = numbers[2]; std::cout << "n = " << n << std::endl; // n = 4 // меняем значение элемента numbers[2] = 12; std::cout << "numbers[2] = " << numbers[2] << std::endl; // numbers[2] = 12 }
С помощью стандартных циклов можно перебрать контейнер array:
#include <iostream> #include <array> #include <string> int main() { const unsigned n = 5; std::array<std::string, n> people { "Tom", "Alice", "Kate", "Bob", "Sam" }; // обращение через индексы for(int i{}; i < n; i++) { std::cout << people[i] << std::endl; } std::cout << std::endl; // перебор последовательности for (auto person : people) { std::cout << person << std::endl; } }
В контейнер array нельзя добавлять новые элементы, так же как и удалять уже имеющиеся. Основные функции типа array, которые мы можем использовать:
size(): возвращает размер контейнера
at(index): возвращает элемент по индексу index
front(): возвращает первый элемент
back(): возвращает последний элемент
fill(n): присваивает всем элементам контейнера значение n
Применение методов:
#include <iostream> #include <array> #include <string> int main() { std::array<std::string, 3> people { "Tom", "Bob", "Sam" }; std::string second = people.at(1); // Bob std::string first = people.front(); // Tom std::string last = people.back(); // Sam std::cout << second << std::endl; // Bob std::cout << first << std::endl; // Tom std::cout << last << std::endl; // Sam // присваиваем всем элементам "Undefined" people.fill("Undefined"); // people = { "Undefined", "Undefined", "Undefined" } // проверяем for (int i{}; i< people.size(); i++) { std::cout << people[i] << std::endl; } }
Несмотря на то, что объекты array похожи на обычные массивы, тип array более гибок. Например, мы не можем присваивать одному массиву напрямую значения второго массива. В то же время объекту array мы можем передавать данные другого объекта array:
std::array<int, 5> numbers1 { 1, 2, 3, 4, 5 }; std::array<int, 5> numbers2 = numbers1; // так можно сделать int nums1[] = { 1,2,3,4,5 }; //int nums2[] = nums1; // так нельзя следать
Также мы можем сравнивать два контейнера array:
std::array<int, 5> numbers1 { 1, 2, 3, 4, 5 }; std::array<int, 5> numbers2 { 1, 2, 3, 4, 5 }; std::cout << std::boolalpha << (numbers1 == numbers2) << std::endl; // true std::cout << std::boolalpha << (numbers1 != numbers2) << std::endl; // false std::cout << std::boolalpha << (numbers1 > numbers2) << std::endl; // false std::cout << std::boolalpha << (numbers1 < numbers2) << std::endl; // false
Два контейнера сравниваются поэлементно. Так, в примере выше очевидно, что контейнеры numbers1 и numbers2 равны. Тогда как сравнение массивов начиная со стандарта C++20 объявлено устаревшим.