Почему линукс использует swap-файл, часть 2
Первая часть маленького «срывания покрова» о работе подсистемы виртуальной памяти, связи механизмов mmap, разделяемых библиотек и кэшей вызвало такое бурное обсуждение, что я не смог удержаться от того, чтобы не продолжить исследование на практике
Поэтому, сегодня мы сделаем… Крошечную лабораторную работу. В виде крошечной же программы на C, которую мы напишем, скомпилируем и проверим в деле — со свапом и без свапа.
Программа делает очень простую вещь — она запрашивает большой кусок памяти, обращается к нему и активно с ним работает. Чтобы не мучаться с загрузкой каких-либо библиотек, мы просто создадим большой файл, который отобразим в память так, как это делает система при загрузке разделяемых библиотек.
А вызов кода из этой «библиотеки» мы просто эмулируем чтением из такого mmap-нутого файла.
Программа сделает несколько итераций, на каждой итерации она будет параллельно обращаться к «коду» и к одному из участков большого сегмента данных.
И, чтобы не писать лишнего кода, мы определим две константы, которые определят размер «сегмента кода» и общий размер оперативной памяти:
- MEM_GBYTES — размер оперативной памяти для теста
- LIB_GBYTES — размер «кода»
- DATA_GBYTES = MEM_GBYTES — 2
- DATA_GBYTES + LIB_GBYTES = MEM_GBYTES + 1
- MEM_GBYTES = 16
- DATA_GBYTES = 14 — значит «данных» будет 14GB, то есть «памяти достаточно»
- Swap size = 16GB
Текст программы
#include #include #include #include #include #include #define GB 1073741824l #define MEM_SIZE 16 #define LIB_GBYTES 3 #define DATA_GBYTES (MEM_SIZE - 2) long random_read(char * code_ptr, char * data_ptr, size_t size) < long rbt = 0; for (unsigned long i=0 ; ireturn rbt; > int main() < size_t libsize = LIB_GBYTES * GB; size_t datasize = DATA_GBYTES * GB; int fd; char * dataptr; char * libptr; srandom(256); if ((fd = open("library.bin", O_RDONLY)) < 0) < printf("Required library.bin of size %ld\n", libsize); return 1; >if ((libptr = mmap(NULL, libsize, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) < printf("Failed build libptr due %d\n", errno); return 1; >if ((dataptr = mmap(NULL, datasize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) < printf("Failed build dataptr due %d\n", errno); return 1; >printf("Preparing test . \n"); memset(dataptr, 0, datasize); printf("Doing test . \n"); unsigned long chunk_size = GB; unsigned long chunk_count = (DATA_GBYTES - 3) * GB / chunk_size; for (unsigned long chunk=0 ; chunk < chunk_count; chunk++) < printf("Iteration %d of %d\n", 1 + chunk, chunk_count); random_read(libptr, dataptr + (chunk * chunk_size), libsize); >return 0; >
Тест без использования swap
Запрещаем swap указав vm.swappines=0 и запускаем тест
$ time ./swapdemo Preparing test . Killed real 0m6,279s user 0m0,459s sys 0m5,791s
Что произошло? Значение swappiness=0 отключило свап — анонимные страницы в него больше не вытесняются, то есть данные всегда в памяти. Проблема в том, что оставшихся 2GB не хватило для работающих в фоне Chrome и VSCode, и OOM-killer убил тестовую программу. А заодно нехватка памяти похоронила вкладку Chrome, в которой я писал эту статью. И мне это не понравилось — пусть даже автоматическое сохранение сработало. Я не люблю когда мои данные «хоронят».
Включенный swap
Выставляем vm_swappines = 60 (по умолчанию)
Запускаем тест:
$ time ./swapdemo Preparing test . Doing test . Iteration 1 of 11 Iteration 2 of 11 Iteration 3 of 11 Iteration 4 of 11 Iteration 5 of 11 Iteration 6 of 11 Iteration 7 of 11 Iteration 8 of 11 Iteration 9 of 11 Iteration 10 of 11 Iteration 11 of 11 real 1m55,291s user 0m2,692s sys 0m20,626s
Tasks: 298 total, 2 running, 296 sleeping, 0 stopped, 0 zombie %Cpu(s): 0,6 us, 3,1 sy, 0,0 ni, 85,7 id, 10,1 wa, 0,5 hi, 0,0 si, 0,0 st MiB Mem : 15670,0 total, 156,0 free, 577,5 used, 14936,5 buff/cache MiB Swap: 16384,0 total, 12292,5 free, 4091,5 used. 3079,1 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 10393 viking 20 0 17,0g 14,2g 14,2g D 17,3 93,0 0:18.78 swapdemo 136 root 20 0 0 0 0 S 9,6 0,0 4:35.68 kswapd0
Плохой-плохой линукс. Он использует swap почти на 4 гигабайт хотя у него 14 гигабайт кэша и 3 гигабайта доступно! У линукса неправильные настройки! Плохой outlingo, плохие старые админы, они ничего не понимают, они сказали включить swap и теперь у меня из-за них система свапится и плохо работает. Надо отключить swap как советуют намного более молодые и перспективные интернет-эксперты, ведь они точно знают что делать!
Ну … Пусть будет так. Давайте максимально отключим свап по советам экспертов?
Тест почти без swap
Выставляем vm_swappines = 1
Это значение приведет к тому, что свапинг анонимных страниц будет производиться только если нет другого выхода.
Я верю Крису Дауну, поскольку считаю что он отличный инженер и знает что говорит, когда объясняет что swap-файл позволяет системе лучше работать. Поэтому, ожидая, что, «что-то» пойдет «не так» и возможно система будет ужасно неэффективно работать, я заранее подстраховался и запустил тестовую программу, лимитировав её таймером, чтобы увидеть хотя бы ее аварийное завершение.
Сначала рассмотрим вывод top:
Tasks: 302 total, 1 running, 301 sleeping, 0 stopped, 0 zombie %Cpu(s): 0,2 us, 4,7 sy, 0,0 ni, 84,6 id, 10,0 wa, 0,4 hi, 0,0 si, 0,0 st MiB Mem : 15670,0 total, 162,8 free, 1077,0 used, 14430,2 buff/cache MiB Swap: 20480,0 total, 18164,6 free, 2315,4 used. 690,5 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 6127 viking 20 0 17,0g 13,5g 13,5g D 20,2 87,9 0:10.24 swapdemo 136 root 20 0 0 0 0 S 17,2 0,0 2:15.50 kswapd0
Ура?! Свап используется всего лишь на 2.5 гигабайт, что почти 2 в два раза меньше чем в тесте со включенным swap (и swappiness=60). Свапа используется меньше. Свободной памяти тоже меньше. И наверное, мы можем смело отдать победу молодым экспертам. Но вот что странно — наша программа так и не смогла завершить даже 1 (ОДНОЙ!) итерации за 2 (ДВЕ!) минуты:
$ < sleep 120 ; killall swapdemo ; >& [1] 6121 $ time ./swapdemo Preparing test … Doing test … Iteration 1 of 11 [1]+ Done < sleep 120; killall swapdemo; >Terminated real 1m58,791s user 0m0,871s sys 0m23,998s
Повторим — программа не смогла завершить 1 итерацию за 2 минуты хотя в предыдущем тесте она сделала 11 итераций за 2 минуты — то есть с почти отключенным свапом программа работает более чем в 10(!) раз медленнее.
Но есть один плюс — ни одной вкладки Chrome не пострадало. И это хорошо.
Тест с полным отключением swap
Но может быть, просто «задавить» свап через swappiness недостаточно, и его надо полностью отключать? Естественно, что надо проверить и эту теорию. Мы сюда тесты пришли провести, или что?
Это идеальный случай:
- унас нет свопа и все наши данные будут гарантированно в памяти
- свап не будет использоваться даже случайно, потому что его нет
К сожалению, результат запуска тестовой программы аналогичный — не завершилось даже одной итерации.
Tasks: 217 total, 1 running, 216 sleeping, 0 stopped, 0 zombie %Cpu(s): 0,0 us, 2,2 sy, 0,0 ni, 85,2 id, 12,6 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 15670,0 total, 175,2 free, 331,6 used, 15163,2 buff/cache MiB Swap: 0,0 total, 0,0 free, 0,0 used. 711,2 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 136 root 20 0 0 0 0 S 12,5 0,0 3:22.56 kswapd0 7430 viking 20 0 17,0g 14,5g 14,5g D 6,2 94,8 0:14.94 swapdemo
Почему это происходит
Объяснение очень простое — “сегмент кода” который мы подключаем через mmap (libptr) лежит в кэше. Поэтому когда мы запрещаем (или почти запрещаем) swap тем или иным способом, не важно каким — физическим ли отключением swap, или через vm.swappines=0|1 — это всегда заканчивается одним и тем же сценарием — вымыванием mmap’нутого файла из кэша и последующей его загрузкой с диска. А библиотеки загружаются именно через mmap, и чтобы убедиться в этом, достаточно просто сделать ls -l /proc//map_files:
$ ls -l /proc/8253/map_files/ | head -n 10 total 0 lr-------- 1 viking viking 64 фев 7 12:58 556799983000-55679998e000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 55679998e000-5567999af000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 5567999af000-5567999bf000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 5567999c0000-5567999c4000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 5567999c4000-5567999c5000 -> /usr/libexec/gnome-session-binary lr-------- 1 viking viking 64 фев 7 12:58 7fb22a033000-7fb22a062000 -> /usr/share/glib-2.0/schemas/gschemas.compiled lr-------- 1 viking viking 64 фев 7 12:58 7fb22b064000-7fb238594000 -> /usr/lib/locale/locale-archive lr-------- 1 viking viking 64 фев 7 12:58 7fb238594000-7fb2385a7000 -> /usr/lib64/gvfs/libgvfscommon.so lr-------- 1 viking viking 64 фев 7 12:58 7fb2385a7000-7fb2385c3000 -> /usr/lib64/gvfs/libgvfscommon.so
И, как мы рассматривали в первой части статьи, система в условиях фактической нехватки памяти при отключенном свапинге анонимных страниц выберет единственный вариант который её оставил владелец, отключивший свап. И этот вариант — реклейминг (освобождение) чистых страниц, занимаемых под данные mmap-нутых библиотек.
Заключение
Активное использование методики распространения программ «всё свое везу с собой» (flatpak, snap, docker image) приводит к тому, что количество кода, который подключается через mmap, существенно увеличивается.
Это может привести к тому, что использование «экстремальных оптимизаций», связанных с настройкой/отключением swap, может привести к совершенно неожиданным эффектам, потому, что swap-файл — это механизм оптимизации подсистемы виртуальной памяти в условиях memory pressure, а available memory это совсем не «неиспользуемая память», а сумма размеров кэша и свободной памяти.
Отключая swap-файл, вы не «убираете неправильный вариант», а «не оставляете вариантов»
Следует очень осторожно интерпретировать данные о потреблении памтяи процессом — VSS и RSS. Они отображают «текущее состояние» а не «оптимальное состояние».
Если вы не хотите, чтобы система использовала свап — добавьте ей памяти но не отключайте свап. Отключение свапа на пороговых уровнях сделает ситуацию значительно хуже, чем она была бы, если бы система немного отсвапилась.
P.S.: В обсуждениях регулярно задаются вопросы «а вот если включить сжатие памяти через zram. ». Мне стало интересно, и я провел соответствующие тесты: если включить zram и swap, как это сделано по умолчанию в Fedora, то время работы ускоряется примерно до 1 минуты.
Но причина этого то, что страницы с нулями очень хорошо сжимаются, поэтому на самом деле данные уезжают не в swap, а хранятся в сжатом виде в оперативной памяти. Если заполнить сегмент данных случайными плохосжимаемыми данными, картина станет не такой эффектной и время работы теста опять же увеличится до 2 минут, что сравнимо (и даже чуть хуже), чем у «честного» swap-файла.
- Настройка Linux
- Серверное администрирование
- Разработка под Linux
Swap (Русский)
Состояние перевода: На этой странице представлен перевод статьи Swap. Дата последней синхронизации: 15 июня 2018. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.
- fstab (Русский)
- Управление питанием/Ждущий и спящий режимы#Гибернация
- Zswap
- Swap on video ram
- ZFS#Swap volume
- dm-crypt/Swap encryption
Эта страница дает ознакомление с пространством подкачки и подкачкой страниц в GNU/Linux. Охватывает создание, активацию файлов и разделов подкачки.
Linux делит свою физическую RAM (оперативную память) на кусочки памяти, называемые страницами. Подкачка (swapping) это процесс, когда страницы памяти копируются на предварительно сконфигурированное пространство на жестком диске, называемое пространством подкачки, чтобы освободить эту страницу из памяти. Суммарный размер оперативной памяти и пространства подкачки это количество доступной виртуальной памяти.
Поддержка подкачки обеспечивается ядром Linux и утилитами в пользовательском пространстве из util-linux пакета.
Пространство подкачки
Пространство подкачки может быть разделом диска или файлом. Пользователи могут создать пространство подкачки во время установки или позднее в любое желаемое время. Пространство подкачки может быть использовано для двух целей, расширить виртуальную память за пределы установленной оперативной памяти (RAM), а также для сохранения данных при гибернации (suspend-to-disk).
Иногда стоит включать Swap в зависимости от установленной оперативной памяти и количества требований для запуска желаемых программ. Если количество оперативной памяти меньше требуемого, тогда стоит включить подкачку. Это позволяет избежать состояния нехватки памяти (OOM), при котором механизм ядра Linux, OOM Killer, будет автоматически пытаться освободить память, убивая процессы. Чтобы увеличить количество виртуальной памяти до требуемого уровня, добавьте необходимую разницу как пространство подкачки. Например, если программа требует 7,5 GB памяти для запуска, а у вас установлено 4 GB оперативной памяти, добавьте разницу 3,5 GB как подкачку. В будущем добавляйте больше пространства к подкачке, учитывая требования. Это вопрос личных предпочтений если вы считаете, что программы должны быть убиты, вместо включения подкачки. Самый большой недостаток в подкачке это снижение производительности, см. раздел #Производительность
Для проверки статуса подкачки, используйте:
$ swapon --show
$ free -h
free также покажет недостаток памяти, который может быть исправлен включением или увеличением подкачки.
Примечание: Преимущества в производительности между файлом и разделом подкачки нет, оба варианта обрабатываются одинаково.
Раздел подкачки
Раздел подкачки может быть создан различными GNU/Linux утилитами разметки. Разделы подкачки обычно обозначаются как тип 82 . Хотя есть возможность использовать разные типы как подкачку, рекомендуется использовать тип 82 , в большинстве случаев systemd, будет автоматически определять его и монтировать (см. ниже)
Для установки раздела как область Linux подкачки, можно использовать mkswap . Например:
# mkswap /dev/sdxy
Важно: Все данные на указанном разделе будут утеряны.
Для подключения устройства как подкачку:
# swapon /dev/sdxy
Чтобы подключить этот раздел подкачки при загрузке, добавьте запись в fstab:
UUID= none swap defaults 0 0
где может быть получен из команды:
lsblk -no UUID /dev/sdxy
Совет: Предпочтительно использовать UUID и LABEL, чем имена устройств полученные от ядра (/dev/sd*), т.к. порядок устройств может измениться в будущем. Смотри fstab.
- Эта fstab запись необязательна если раздел подкачки находится на устройстве, использующий GPT разметку, см. следующий подраздел.
- Если используется SSD с поддержкой TRIM, учтите использование defaults,discard в fstab строке подключения подкачки. Если вручную активировать подкачку с помощью swapon, используйте параметр -d / —discard , который делает тоже самое. Подробности смотри в swapon(8) .
Важно: Включение discard в RAID установке с использованием mdadm, приведёт к блокировке системы при загрузке и во время выполнения, если использовать swapon.
Активация используя systemd
Активация разделов подкачки в systemd базируется на двух различных механизмах. Оба исполняются в /usr/lib/systemd/system-generators . Генераторы запускаются при старте системы и создают нативные systemd юниты для монтирования. Первый systemd-fstab-generator , читает fstab, чтобы генерировать юниты, включая юнит для подкачки. Второй systemd-gpt-auto-generator , осматривает корневой диск, чтобы генерировать юниты. Это операция проходит только на GPT дисках и может идентифицировать разделы подкачки по их тип коду 82 .
Отключение подкачки
Чтобы деактивировать определенное пространство подкачки:
# swapoff /dev/sdxy
Также можно использовать -a ключ, чтобы деактивировать все пространства подкачки.
С тех пор, как systemd управляет подкачкой, она вновь будет активирована при старте системы, для долговременного отключения автоматической активации найденных пространств подкачки, выполните systemctl —type swap , чтобы найти связанные со .swap юниты и замаскируйте (systemctl mask юнит) их.
Файл подкачки
Как альтернатива к созданию целого раздела, файл подкачки даёт возможность менять свой размер на лету, а также его гораздо легче полностью удалить. Это может быть особенно важно, если дисковое пространство ограничено (например, небольшие SSD)
Важно: Btrfs не поддерживает файлы подкачки. Несоблюдение этого предупреждения, может стать результатом разрушения файловой системы. Пока что, файл подкачки может быть использован в Btrfs, если смонтирован через loop-устройство, тогда будет сильно уменьшена производительность подкачки.
Вручную
Создание файла подкачки
Использовать под суперпользователем fallocate , чтобы создать файл подкачки размером на свой выбор (M = Mebibytes, G = Gibibytes). Например создание 512 MiB файла подкачки:
# fallocate -l 512M /swapfile
Примечание: fallocate может вызвать проблемы с некоторыми файловыми системами, такими как: F2FS или XFS.[1]. Как вариант, используйте dd, наиболее надёжный, но медленный.
# dd if=/dev/zero of=/swapfile bs=1M count=512
Установите права доступа (всеми читаемый файл подкачки это огромная локальная уязвимость)
# chmod 600 /swapfile
После создания файла нужного размера, форматируйте его в подкачку:
# mkswap /swapfile
Активируйте файл подкачки:
# swapon /swapfile
В завершении, отредактируйте fstab, добавив запись для файла подкачки:
/etc/fstab
/swapfile none swap defaults 0 0
Примечание: Не забудьте добавить discard, если у вас SSD с поддержкой TRIM
# swapon --discard /swapfile
/etc/fstab
/swapfile none swap defaults,discard 0 0
Удаление файла подкачки
Чтобы удалить файл подкачки, сначала нужно отключить подкачку, а затем файл может быть удален:
# swapoff -a # rm -f /swapfile
В завершении, удалите соответствующую запись из /etc/fstab .
Автоматически
systemd-swap
Установить systemd-swap AUR пакет. Установить swapfc_enabled=1 в Swap File Chunked разделе файла /etc/systemd/swap.conf . Start/enable systemd-swap сервис. Посетить страницу авторов на GitHub для получения подробностей и установить рекомендуемую конфигурацию.
Примечание: Если журнал продолжает показывать следующее предупреждение systemd-swap[..]: WARN: swapFC: ENOSPC и файл подкачки не создаётся, вы должны установить параметр swapfc_force_preallocated=1 в /etc/systemd/swap.conf .
Подкачка с USB устройства
Благодаря модульности, предлагаемой Linux, мы можем иметь множество разделов подкачки на различных устройствах. Если у вас полностью заполнен жесткий диск, то можно использовать USB устройство как временный раздел подкачки. Однако, этот метод имеет серьёзные недостатки:
- USB устройство медленнее чем жесткий диск
- Flash память имеет ограниченное количество циклов записи. Использование его как раздела подкачки, может быстро убить его.
Чтобы добавить USB устройство как подкачку, сначала необходимо разметить USB флешку для подкачки как описано в секции #Раздел подкачки.
Далее откройте /etc/fstab и добавьте
pri=0
в опции монтирования первоначальной записи подкачки, таким образом USB подкачка будет иметь приоритет записи над старым разделом.
Данная инструкция будет работать и для других устройств хранения, таких как SD карты и т.д.
Шифрование подкачки
Производительность
Операции подкачки как правило существенно медленнее чем непосредственный доступ к RAM. Отключение подкачки полностью для повышения производительности, иногда может привести к ухудшению, поскольку это уменьшает доступную память для VFS кеша, вызывая более частые и дорогостоящие операции ввода/вывода.
Значения подкачки можно настроить, чтобы помочь производительности:
Swappiness
Swappiness sysctl параметр представляющий частоту использования пространства подкачки. Swappiness может иметь значение от 0 до 100, значение по умолчанию = 60. Низкое значение заставляет ядро избегать подкачки, высокое значение позволяет ядру использовать подкачку наперёд. Использование низкого значения на достаточном количестве памяти, улучшает отзывчивость на многих системах.
Чтобы проверить текущее значение swappiness:
$ cat /sys/fs/cgroup/memory/memory.swappiness
$ cat /proc/sys/vm/swappiness
Примечание: Т.к. /proc менее организован и сохраняется только для обратной совместимости, вместо него предпочтительнее использовать /sys .
Чтобы временно установить значение swappiness:
# sysctl vm.swappiness=10
Чтобы постоянно установить значение swappiness, отредактируйте (создайте) конфигурационный файл sysctl
/etc/sysctl.d/99-sysctl.conf
vm.swappiness=10
Чтобы проверить и больше узнать, почему оно так работает, посмотрите эту статью.
VFS cache pressure
Другой sysctl параметр, который действует на производительность подкачки это vm.vfs_cache_pressure , он контролирует склонность ядра к применению памяти, которая используется для кэширования VFS caches, напротив кэширования страниц и подкачки. Увеличение этого значения увеличивает коэффициент с которым VFS caches применяется[2] [устаревшая ссылка 2020-08-06 ⓘ] . Для подробной информации смотри документацию ядра Linux.
Приоритет
Если у вас больше одного файла или раздела подкачки, вы должны учитывать присвоение приоритетного значения (от 0 до 32767) для каждой области подкачки. Система будет использовать области подкачки с высоким приоритетом, перед использованием областей с низким приоритетом. Например, если у вас быстрый диск ( /dev/sda ) и медленный ( /dev/sdb ), назначьте высокий приоритет для подкачки расположенной на быстром устройстве. Приоритет может быть назначен в fstab как pri параметр:
/dev/sda1 none swap defaults,pri=100 0 0 /dev/sdb2 none swap defaults,pri=10 0 0
Или как параметр в swapon —priority
# swapon --priority 100 /dev/sda1
Если две или более областей будут иметь одинаковый приоритет и он будет самым высоким из доступным приоритетов, то страницы будут распределяться по кругу между областями.
Использование zswap или zram
zswap это особенность ядра Linux, обеспечивающая сжатие обратного кэша для страниц подкачки. Она увеличивает производительность и уменьшает операции ввода/вывода. zram создаёт виртуальный сжатый файл подкачки в памяти, как альтернатива файлу подкачки на диске.
Чередование
Нет необходимости использовать RAID для повышения производительности подкачки. Ядро самостоятельно может чередовать подкачку на нескольких устройствах, если вы присвоите им одинаковый приоритет в /etc/fstab . Для подробной информации смотри The Software-RAID HOWTO.
Retrieved from «https://wiki.archlinux.org/index.php?title=Swap_(Русский)&oldid=787252»
Класс vector
Класс вектора стандартной библиотеки C++ — это шаблон класса для контейнеров последовательности. Вектор хранит элементы заданного типа в линейном расположении и обеспечивает быстрый случайный доступ к любому элементу. Вектор — это предпочтительный контейнер для последовательности, если производительность случайного доступа находится в категории «Премиум».
Синтаксис
template > class vector
Параметры
Type
Тип данных элементов, сохраняемых в векторе.
Allocator
Тип, представляющий сохраненный объект распределителя, содержащий сведения о распределении и отмене распределения памяти для вектора. Этот аргумент является необязательным, и значением по умолчанию является allocator .
Замечания
Для векторов время выполнения вставок и удалений элементов в конце последовательности является постоянной величиной. Время вставки и удаления элементов в середине вектора меняется линейно. Контейнер deque класса быстрее выполняется при вставке и удалении в начале и конце последовательности. Контейнер list класса быстрее выполняется при вставке и удалении в любом расположении в последовательности.
Расширение вектора происходит, когда функции-члену требуется увеличить последовательность в объекте вектора сверх его текущей емкости. Другие операции вставки и стирания могут изменять различные адреса хранения внутри последовательности. Во всех таких случаях итераторы или ссылки, указывающие на изменившиеся части последовательности, становятся недействительными. Если расширения не происходит, действительными остаются только итераторы и ссылки перед точкой вставки или удаления.
Ссылочный vector класс — это вложенный класс, объекты которого могут предоставлять ссылки на элементы (одиночные биты) в объекте vector .
Участники
Конструкторы
| Имя | Описание |
|---|---|
| vector | Создает вектор определенного размера, вектор с элементами определенного значения, вектор с определенным allocator , или вектор как копию какого-либо другого вектора. |
Определения типов
| Имя | Описание |
|---|---|
| [allocator_type] (#allocator_type) | Тип, представляющий класс allocator для объекта вектора. |
| const_iterator | Тип, предоставляющий итератор произвольного доступа, который может читать элемент const в векторе. |
| const_pointer | Тип, предоставляющий указатель на элемент const в векторе. |
| const_reference | Тип, предоставляющий ссылку на const элемент, хранящийся в векторе. Он используется для чтения и выполнения const операций. |
| const_reverse_iterator | Тип, предоставляющий итератор произвольного доступа, который может читать любой элемент const в векторе. |
| difference_type | Тип, представляющий различие между адресами двух элементов в векторе. |
| iterator | Тип, предоставляющий итератор произвольного доступа, который может читать или изменять любой элемент в векторе. |
| pointer | Тип, предоставляющий указатель на элемент в векторе. |
| reference | Тип, предоставляющий ссылку на элемент, хранящийся в векторе. |
| reverse_iterator | Тип, предоставляющий итератор произвольного доступа, который может читать или изменять любой элемент в обратном векторе. |
| size_type | Тип, считающий количество элементов в векторе. |
| value_type | Тип, представляющий тип данных, хранящихся в векторе. |
Функции
| Имя | Описание |
|---|---|
| assign | Удаляет вектор и копирует указанные элементы в пустой вектор. |
| at | Возвращает ссылку на элемент в заданном положении в векторе. |
| back | Возвращает ссылку на последний элемент вектора. |
| begin | Возвращает итератор произвольного доступа, указывающий на первый элемент в векторе. |
| capacity | Возвращает число элементов, которое вектор может содержать без выделения дополнительного пространства. |
| cbegin | Возвращает постоянный итератор произвольного доступа, указывающий на первый элемент в векторе. |
| cend | Возвращает константный итератор произвольного доступа, указывающий на позицию, следующую за концом вектора. |
| crbegin | Возвращает константный итератор, который указывает на первый элемент в обратном векторе. |
| crend | Возвращает константный итератор, который указывает на последний элемент в обратном векторе. |
| clear | Очищает элементы вектора. |
| data | Возвращает указатель на первый элемент в векторе. |
| emplace | Вставляет элемент, созданный на месте, в указанное положение в векторе. |
| emplace_back | Добавляет элемент, созданный на месте, в конец вектора. |
| empty | Проверяет, пуст ли контейнер вектора. |
| end | Возвращает итератор произвольного доступа, который указывает на конец вектора. |
| erase | Удаляет элемент или диапазон элементов в векторе из заданных позиций. |
| front | Возвращает ссылку на первый элемент в векторе. |
| get_allocator | Возвращает объект классу allocator , используемому вектором. |
| insert | Вставляет элемент или многие элементы в вектор по заданной позиции. |
| max_size | Возвращает максимальную длину вектора. |
| pop_back | Удаляет элемент в конце вектора. |
| push_back | Добавляет элемент в конец вектора. |
| rbegin | Возвращает итератор, указывающий на первый элемент в обратном векторе. |
| rend | Возвращает итератор, который указывает на последний элемент в обратном векторе. |
| reserve | Резервирует минимальную длину хранилища для объекта вектора. |
| resize | Определяет новый размер вектора. |
| shrink_to_fit | Удаляет лишнюю емкость. |
| size | Возвращает количество элементов в векторе. |
| swap | Меняет местами элементы двух векторов. |
Операторы
| Имя | Описание |
|---|---|
| operator[] | Возвращает ссылку на элемент вектора в указанной позиции. |
| operator= | Заменяет элементы вектора копией другого вектора. |
allocator_type
Тип, представляющий класс распределителя для объекта вектора.
typedef Allocator allocator_type;
Замечания
allocator_type является синонимом для параметра-шаблона Allocator .
Пример
Пример использования см. в примере get_allocator allocator_type .
assign
Удаляет вектор и копирует указанные элементы в пустой вектор.
void assign(size_type count, const Type& value); void assign(initializer_list init_list); template void assign(InputIterator first, InputIterator last);
Параметры
first
Положение первого элемента в диапазоне копируемых элементов.
last
Положение первого элемента за пределами диапазона копируемых элементов.
count
Количество копий элемента, вставляемых в вектор.
value
Значение элемента, вставляемого в вектор.
init_list
Объект initializer_list, содержащий вставляемые элементы.
Замечания
Во-первых, assign удаляет все существующие элементы в векторе. assign Затем либо вставляет указанный диапазон элементов из исходного вектора в вектор, либо вставляет копии нового указанного элемента значения в вектор.
Пример
/ vector_assign.cpp // compile with: /EHsc #include #include int main() < using namespace std; vectorv1, v2, v3; v1.push_back(10); v1.push_back(20); v1.push_back(30); v1.push_back(40); v1.push_back(50); cout cout cout cout ); for (auto& v : v3) < cout cout
at
Возвращает ссылку на элемент в заданном положении в векторе.
reference at(size_type position); const_reference at(size_type position) const;
Параметры
position
Номер нижнего индекса или позиции элемента, на который включается ссылка в векторе.
Возвращаемое значение
Ссылка на элемент, индекс которого указан в аргументе. Если position размер вектора больше размера, at создается исключение.
Замечания
Если возвращаемое значение at назначено объекту const_reference , объект вектора не может быть изменен. Если возвращаемое значение at присвоено reference , то объект вектора можно изменить.
Пример
// vector_at.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; v1.push_back( 10 ); v1.push_back( 20 ); const int &i = v1.at( 0 ); int &j = v1.at( 1 ); cout
The first element is 10 The second element is 20
back
Возвращает ссылку на последний элемент вектора.
reference back(); const_reference back() const;
Возвращаемое значение
Последний элемент вектора. Если вектор пуст, возвращаемое значение не определено.
Замечания
Если возвращаемое значение back назначено объекту const_reference , объект вектора не может быть изменен. Если возвращаемое значение back присвоено reference , то объект вектора можно изменить.
При компиляции с помощью _ITERATOR_DEBUG_LEVEL 1 или 2 ошибка среды выполнения возникает при попытке доступа к элементу в пустом векторе. Дополнительные сведения см. в разделе "Проверенные итераторы".
Пример
// vector_back.cpp // compile with: /EHsc #include #include int main() < using namespace std; vector v1; v1.push_back( 10 ); v1.push_back( 11 ); int& i = v1.back( ); const int& ii = v1.front( ); cout
begin
Возвращает итератор произвольного доступа, указывающий на первый элемент в векторе.
const_iterator begin() const; iterator begin();
Возвращаемое значение
Итератор произвольного доступа, который указывает на первый элемент в vector или на элемент, следующий за пустым vector . Всегда сравнивайте возвращаемое значение, vector::end чтобы убедиться, что он действителен.
Замечания
Если возвращаемое значение begin назначено объекту vector::const_iterator , vector объект нельзя изменить. Если возвращаемое значение begin назначено объекту vector::iterator , vector объект можно изменить.
Пример
// vector_begin.cpp // compile with: /EHsc #include #include int main() < using namespace std; vectorc1; vector::iterator c1_Iter; vector::const_iterator c1_cIter; c1.push_back(1); c1.push_back(2); cout cout cout
The vector c1 contains elements: 1 2 The vector c1 now contains elements: 20 2
capacity
Возвращает число элементов, которое вектор может содержать без выделения дополнительного пространства.
size_type capacity() const;
Возвращаемое значение
Текущая длина хранилища, выделенного вектору.
Замечания
Функция-член resize будет более эффективной при выделении достаточной памяти для ее размещения. Используйте функцию-член reserve , чтобы указать объем выделенной памяти.
Пример
// vector_capacity.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; v1.push_back( 1 ); cout
The length of storage allocated is 1. The length of storage allocated is now 2.
cbegin
Возвращает итератор const , направленный на первый элемент в диапазоне.
const_iterator cbegin() const;
Возвращаемое значение
Итератор случайного доступа const , который указывает на первый элемент диапазона или расположение прямо за концом пустого диапазона ( cbegin() == cend() для пустого диапазона).
Замечания
При возвращаемом значении cbegin элементы в диапазоне не могут быть изменены.
Эту функцию-член можно использовать вместо функции-члена begin() , чтобы гарантировать, что возвращаемое значение будет const_iterator . Как правило, он используется с ключевое слово вычета auto типов, как показано в следующем примере. В примере Container следует рассматривать как изменяемый (не- const ) контейнер любого вида, который поддерживает begin() и cbegin() .
auto i1 = Container.begin(); // i1 is Container::iterator auto i2 = Container.cbegin(); // i2 is Container::const_iterator
cend
Возвращает итератор, указывающий const на элемент после последнего элемента вектора.
const_iterator cend() const;
Возвращаемое значение
Итератор const последнего итератора для вектора. Он указывает на элемент после последнего элемента вектора. Этот элемент является заполнителем и не должен быть разоменован. Используйте его только для сравнения. Если вектор пуст, то vector::cend() == vector::cbegin() .
Замечания
cend используется для проверки того, прошел ли итератор конец диапазона.
Эту функцию-член можно использовать вместо функции-члена end() , чтобы гарантировать, что возвращаемое значение будет const_iterator . Как правило, он используется с ключевое слово вычета auto типов, как показано в следующем примере. В примере Container следует рассматривать как изменяемый (не- const ) контейнер любого вида, который поддерживает end() и cend() .
auto i1 = Container.end(); // i1 is Container::iterator auto i2 = Container.cend(); // i2 is Container::const_iterator
Возвращаемое cend значение не должно быть разоменовывано. Используйте его только для сравнения.
clear
Очищает элементы вектора.
void clear();
Пример
// vector_clear.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; v1.push_back( 10 ); v1.push_back( 20 ); v1.push_back( 30 ); cout
The size of v1 is 3 The size of v1 after clearing is 0
const_iterator
Тип, предоставляющий итератор произвольного доступа, который может читать элемент const в векторе.
typedef implementation-defined const_iterator;
Замечания
Тип const_iterator нельзя использовать для изменения значения элемента.
Пример
Пример использования back см. в разделе const_iterator .
const_pointer
Тип, предоставляющий указатель на элемент const в векторе.
typedef typename Allocator::const_pointer const_pointer;
Замечания
Тип const_pointer нельзя использовать для изменения значения элемента.
Для доступа к элементу вектора обычно используется iterator.
const_reference
Тип, предоставляющий ссылку на const элемент, хранящийся в векторе. Он используется для чтения и выполнения const операций.
typedef typename Allocator::const_reference const_reference;
Замечания
Тип const_reference нельзя использовать для изменения значения элемента.
Пример
// vector_const_ref.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; v1.push_back( 10 ); v1.push_back( 20 ); const vector v2 = v1; const int &i = v2.front( ); const int &j = v2.back( ); cout
The first element is 10 The second element is 20
const_reverse_iterator
Тип, предоставляющий итератор произвольного доступа, который может читать любой элемент const в векторе.
typedef std::reverse_iterator const_reverse_iterator;
Замечания
Тип const_reverse_iterator не может изменить значение элемента и используется для итерации по вектору в обратном направлении.
Пример
См rbegin . пример объявления и использования итератора.
crbegin
Возвращает константный итератор, который указывает на первый элемент в обратном векторе.
const_reverse_iterator crbegin() const;
Возвращаемое значение
Итератор обратного случайного доступа констант, обращаюющийся к первому элементу в обратном vector или адресу, который был последним элементом в необратимом vector .
Замечания
Возвращаемое значение crbegin vector объекта невозможно изменить.
Пример
// vector_crbegin.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::iterator v1_Iter; vector ::const_reverse_iterator v1_rIter; v1.push_back( 1 ); v1.push_back( 2 ); v1_Iter = v1.begin( ); cout
The first element of vector is 1. The first element of the reversed vector is 2.
crend
Возвращает обратный итератор, указывающий const на элемент после последнего элемента обратного вектора.
const_reverse_iterator crend() const;
Возвращаемое значение
Обратный const итератор в прошлом для обратного вектора. Он указывает на элемент после последнего элемента обратного вектора, который совпадает с элементом перед первым элементом ненавернутого вектора. Этот элемент является заполнителем и не должен быть разоменован. Используйте его только для сравнения.
Замечания
crend используется с обратным vector так же, как vector::cend используется с vector .
Возвращаемое значение crend (подходящее уменьшение), vector объект не может быть изменен.
crend используется, чтобы проверить, достиг ли итератор конца vector .
Возвращаемое crend значение не должно быть разоменовывано. Используйте его только для сравнения.
Пример
// vector_crend.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::const_reverse_iterator v1_rIter; v1.push_back( 1 ); v1.push_back( 2 ); for ( v1_rIter = v1.rbegin( ) ; v1_rIter != v1.rend( ) ; v1_rIter++ ) cout
data
Возвращает указатель на первый элемент в векторе.
const_pointer data() const; pointer data();
Возвращаемое значение
Указатель на первый элемент в vector расположении или в расположении успешно пустой vector .
Пример
// vector_data.cpp // compile with: /EHsc #include #include int main() < using namespace std; vectorc1; vector::pointer c1_ptr; vector::const_pointer c1_cPtr; c1.push_back(1); c1.push_back(2); cout cout cout
The vector c1 contains elements: 1 2 The vector c1 now contains elements: 20 2
difference_type
Тип, предоставляющий разницу между двумя итераторами, ссылающимися на элементы в одном и том же векторе.
typedef typename Allocator::difference_type difference_type;
Замечания
difference_type также можно описать как число элементов между двумя указателями, так как указатель на элемент содержит его адрес.
Для доступа к элементу вектора обычно используется iterator.
Пример
// vector_diff_type.cpp // compile with: /EHsc #include #include #include int main( ) < using namespace std; vector c1; vector ::iterator c1_Iter, c2_Iter; c1.push_back( 30 ); c1.push_back( 20 ); c1.push_back( 30 ); c1.push_back( 10 ); c1.push_back( 30 ); c1.push_back( 20 ); c1_Iter = c1.begin( ); c2_Iter = c1.end( ); vector ::difference_type df_typ1, df_typ2, df_typ3; df_typ1 = count( c1_Iter, c2_Iter, 10 ); df_typ2 = count( c1_Iter, c2_Iter, 20 ); df_typ3 = count( c1_Iter, c2_Iter, 30 ); cout
The number '10' is in c1 collection 1 times. The number '20' is in c1 collection 2 times. The number '30' is in c1 collection 3 times.
emplace
Вставляет элемент, созданный на месте, в указанное положение в векторе.
template iterator emplace( const_iterator position, Types&&. args);
Параметры
position
Позиция в vector месте вставки первого элемента.
args
Аргументы конструктора. Функция определяет перегрузку конструктора, которую нужно вызвать, на основе переданных аргументов.
Возвращаемое значение
Функция возвращают итератор, указывающий на положение вставки нового элемента в vector .
Замечания
Любая операция вставки может быть дорогой, см vector . класс для обсуждения vector производительности.
Пример
// vector_emplace.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::iterator Iter; v1.push_back( 10 ); v1.push_back( 20 ); v1.push_back( 30 ); cout << "v1 =" ; for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) cout << " " << *Iter; cout << endl; // initialize a vector of vectors by moving v1 vector < vector > vv1; vv1.emplace( vv1.begin(), move( v1 ) ); if ( vv1.size( ) != 0 && vv1[0].size( ) != 0 ) < cout >
v1 = 10 20 30 vv1[0] = 10 20 30
emplace_back
Добавляет элемент, созданный на месте, в конец вектора.
template void emplace_back(Types&&. args);
Параметры
args
Аргументы конструктора. Функция определяет перегрузку конструктора, которую нужно вызвать, на основе переданных аргументов.
Пример
#include struct obj < obj(int, double) <>>; int main() < std::vectorv; v.emplace_back(1, 3.14); // obj in created in place in the vector >
empty
Проверяет, пуст ли вектор.
bool empty() const;
Возвращаемое значение
true Значение false Значение , если вектор не пуст.
Пример
// vector_empty.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; v1.push_back( 10 ); if ( v1.empty( ) ) cout
The vector is not empty.
end
Возвращает итератор, указывающий на элемент после последнего элемента вектора.
iterator end(); const_iterator end() const;
Возвращаемое значение
Итератор последнего итератора для вектора. Он указывает на элемент после последнего элемента вектора. Этот элемент является заполнителем и не должен быть разоменован. Используйте его только для сравнения. Если вектор пуст, то vector::end() == vector::begin() .
Замечания
Если возвращаемое значение end присваивается переменной типа const_iterator , объект вектора не может быть изменен. Если возвращаемое значение end присваивается переменной типа iterator , объект вектора можно изменить.
Пример
// vector_end.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::iterator v1_Iter; v1.push_back( 1 ); v1.push_back( 2 ); for ( v1_Iter = v1.begin( ) ; v1_Iter != v1.end( ) ; v1_Iter++ ) cout
erase
Удаляет элемент или диапазон элементов в векторе из заданных позиций.
iterator erase( const_iterator position); iterator erase( const_iterator first, const_iterator last);
Параметры
position
Положение элемента, удаляемого из вектора.
first
Положение первого элемента, удаляемого из вектора.
last
Положение после последнего элемента, удаляемого из вектора.
Возвращаемое значение
Итератор, указывающий на первый элемент, оставшийся после удаленных элементов, или на указатель конца вектора, если такого элемента не существует.
Пример
// vector_erase.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::iterator Iter; v1.push_back( 10 ); v1.push_back( 20 ); v1.push_back( 30 ); v1.push_back( 40 ); v1.push_back( 50 ); cout
v1 = 10 20 30 40 50 v1 = 20 30 40 50 v1 = 20 50
front
Возвращает ссылку на первый элемент в векторе.
reference front(); const_reference front() const;
Возвращаемое значение
Ссылка на первый элемент в объекте вектора. Если вектор пуст, возвращаемое значение не определено.
Замечания
Если возвращаемое значение front назначено объекту const_reference , объект вектора не может быть изменен. Если возвращаемое значение front присвоено reference , то объект вектора можно изменить.
При компиляции с помощью _ITERATOR_DEBUG_LEVEL 1 или 2 ошибка среды выполнения возникает при попытке доступа к элементу в пустом векторе. Дополнительные сведения см. в разделе "Проверенные итераторы".
Пример
// vector_front.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; v1.push_back( 10 ); v1.push_back( 11 ); int& i = v1.front( ); const int& ii = v1.front( ); coutget_allocator
Возвращает копию объекта allocator, используемого для создания вектора.
Allocator get_allocator() const;Возвращаемое значение
Распределитель, используемый вектором.
Замечания
Распределители для класса вектора определяют, как этот класс управляет хранилищем. Распределители по умолчанию для классов контейнеров из стандартной библиотеки C++ достаточны для большинства задач программирования. Написание и использование собственного класса распределителя — это расширенная функция C++.
Пример
// vector_get_allocator.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; // The following lines declare objects that use the default allocator. vectorv1; vectorv2 = vector (allocator( )) ; // v3 will use the same allocator class as v1 vector v3( v1.get_allocator( ) ); vector::allocator_type xvec = v3.get_allocator( ); // You can now call functions on the allocator class used by vec > insert
Вставляет элемент или многие элементы или диапазон элементов в вектор по заданной позиции.
iterator insert( const_iterator position, const Type& value); iterator insert( const_iterator position, Type&& value); void insert( const_iterator position, size_type count, const Type& value); template void insert( const_iterator position, InputIterator first, InputIterator last);Параметры
position
Позиция в векторе, куда вставляется первый элемент.value
Значение элемента, вставляемого в вектор.count
Количество элементов, вставляемых в вектор.first
Положение первого элемента в диапазоне копируемых элементов.last
Положение первого элемента после диапазона копируемых элементов.Возвращаемое значение
Две первые функции insert возвращают итератор, указывающий на положение вставки нового элемента в вектор.
Замечания
Используемые в качестве предусловия first и last не должны быть итераторами в векторе, в противном случае поведение будет неопределенным. Любая операция вставки может быть дорогой, см vector . класс для обсуждения vector производительности.
Пример
// vector_insert.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::iterator Iter; v1.push_back( 10 ); v1.push_back( 20 ); v1.push_back( 30 ); cout << "v1 =" ; for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) cout << " " << *Iter; cout << endl; v1.insert( v1.begin( ) + 1, 40 ); cout << "v1 ="; for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) cout << " " << *Iter; cout << endl; v1.insert( v1.begin( ) + 2, 4, 50 ); cout << "v1 ="; for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) cout << " " << *Iter; cout << endl; const auto v2 = v1; v1.insert( v1.begin( )+1, v2.begin( )+2, v2.begin( )+4 ); cout << "v1 ="; for (Iter = v1.begin( ); Iter != v1.end( ); Iter++ ) cout << " " << *Iter; cout << endl; // initialize a vector of vectors by moving v1 vector < vector > vv1; vv1.insert( vv1.begin(), move( v1 ) ); if ( vv1.size( ) != 0 && vv1[0].size( ) != 0 ) < cout >v1 = 10 20 30 v1 = 10 40 20 30 v1 = 10 40 50 50 50 50 20 30 v1 = 10 50 50 40 50 50 50 50 20 30 vv1[0] = 10 50 50 40 50 50 50 50 20 30iterator
Тип, предоставляющий итератор произвольного доступа, который может читать или изменять любой элемент в векторе.
typedef implementation-defined iterator;Замечания
Тип iterator можно использовать для изменения значения элемента.
Пример
Пример см. в примере begin .
max_size
Возвращает максимальную длину вектора.
size_type max_size() const;Возвращаемое значение
Максимально возможная длина вектора.
Пример
// vector_max_size.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::size_type i; i = v1.max_size( ); coutoperator[]
Возвращает ссылку на элемент вектора в указанной позиции.
reference operator[](size_type position); const_reference operator[](size_type position) const;Параметры
position
Позиция элемента вектора.Возвращаемое значение
Если заданная позиция больше или равна размеру контейнера, результат не определен.
Замечания
Если возвращаемое значение operator[] назначено объекту const_reference , объект вектора не может быть изменен. Если возвращаемое значение operator[] присвоено ссылке, то объект вектора можно изменить.
При компиляции, _ITERATOR_DEBUG_LEVEL определяемой как 1 или 2, возникает ошибка среды выполнения при попытке получить доступ к элементу за пределами вектора. Дополнительные сведения см. в разделе "Проверенные итераторы".
Пример
// vector_op_ref.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; v1.push_back( 10 ); v1.push_back( 20 ); int& i = v1[1]; coutoperator=
Заменяет элементы вектора копией другого вектора.
vector& operator=(const vector& right); vector& operator=(vector&& right);Параметры
right
Копируемый vector в . vectorЗамечания
После удаления всех существующих элементов в объекте vector operator= копирует или перемещает содержимое right в объект vector .
Пример
// vector_operator_as.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vectorv1, v2, v3; vector::iterator iter; v1.push_back(10); v1.push_back(20); v1.push_back(30); v1.push_back(40); v1.push_back(50); coutpointer
Тип, предоставляющий указатель на элемент в векторе.
typedef typename Allocator::pointer pointer;Замечания
Тип pointer можно использовать для изменения значения элемента.
Пример
// vector_pointer.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vectorv; v.push_back( 11 ); v.push_back( 22 ); vector::pointer ptr = &v[0]; cout11 22 44pop_back
Удаляет элемент в конце вектора.
void pop_back();Замечания
Пример кода см. в разделе vector::push_back().
push_back
Добавляет элемент в конец вектора.
void push_back(const T& value); void push_back(T&& value);Параметры
value
Значение, назначаемое элементу, который добавляется в конец вектора.Пример
// compile with: /EHsc /W4 #include #include using namespace std; template void print_elem(const T& t) < cout template void print_collection(const T& t) < cout cout int main() < vectorv; for (int i = 0; i < 10; ++i) < v.push_back(10 + i); >cout >rbegin
Возвращает итератор, указывающий на первый элемент в обратном векторе.
reverse_iterator rbegin(); const_reverse_iterator rbegin() const;Возвращаемое значение
Обратный итератор произвольного доступа, указывающий на первый элемент в обратном векторе или на последний элемент в исходном векторе.
Замечания
Если возвращаемое значение rbegin назначено объекту const_reverse_iterator , объект вектора не может быть изменен. Если возвращаемое значение rbegin присвоено reverse_iterator , то объект вектора можно изменить.
Пример
// vector_rbegin.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::iterator v1_Iter; vector ::reverse_iterator v1_rIter; v1.push_back( 1 ); v1.push_back( 2 ); v1_Iter = v1.begin( ); coutThe first element of vector is 1. The first element of the reversed vector is 2.reference
Тип, предоставляющий ссылку на элемент, хранящийся в векторе.
typedef typename Allocator::reference reference;Пример
См at . пример использования reference в классе векторов.
rend
Возвращает обратный итератор, указывающий на элемент после последнего элемента обратного вектора.
const_reverse_iterator rend() const; reverse_iterator rend();Возвращаемое значение
Обратный итератор в прошлом для обратного вектора. Он указывает на элемент после последнего элемента обратного вектора, который совпадает с элементом перед первым элементом ненавернутого вектора. Этот элемент является заполнителем и не должен быть разоменован. Используйте его только для сравнения.
Замечания
rend используется с обратным вектором так же, как end и с вектором.
Если возвращаемое значение rend назначено объекту const_reverse_iterator , объект вектора не может быть изменен. Если возвращаемое значение rend присвоено reverse_iterator , то объект вектора можно изменить.
rend используется, чтобы проверить, достиг ли обратный итератор конца вектора.
Возвращаемое rend значение не должно быть разоменовывано. Используйте его только для сравнения.
Пример
// vector_rend.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::reverse_iterator v1_rIter; v1.push_back( 1 ); v1.push_back( 2 ); for ( v1_rIter = v1.rbegin( ) ; v1_rIter != v1.rend( ) ; v1_rIter++ ) coutreserve
Резервирует минимальную длину хранилища для объекта вектора, при необходимости выделяя пространство.
void reserve(size_type count);Параметры
count
Минимальная длина хранилища, выделяемого для вектора.Пример
// vector_reserve.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; //vector ::iterator Iter; v1.push_back( 1 ); coutCurrent capacity of v1 = 1 Current capacity of v1 = 20resize
Определяет новый размер вектора.
void resize(size_type new_size); void resize(size_type new_size, Type value);Параметры
new_size
Новый размер вектора.value
Значение инициализации новых элементов, добавленных в вектор, если новый размер больше исходного. Если значение опущено, новые объекты используют конструктор по умолчанию.Замечания
Если размер контейнера меньше запрошенного размера, new_size resize добавляет элементы в вектор, пока он не достигнет запрошенного размера. Если размер контейнера превышает запрошенный размер, удаляет элементы, ближайшие к концу контейнера, resize пока он не достигнет размера new_size . Никаких действий не выполняется, если размер контейнера совпадает с запрошенным размером.
size отражает текущий размер вектора.
Пример
// vectorsizing.cpp // compile with: /EHsc /W4 // Illustrates vector::reserve, vector::max_size, // vector::resize, vector::resize, and vector::capacity. // // Functions: // // vector::max_size - Returns maximum number of elements vector could // hold. // // vector::capacity - Returns number of elements for which memory has // been allocated. // // vector::size - Returns number of elements in the vector. // // vector::resize - Reallocates memory for vector, preserves its // contents if new size is larger than existing size. // // vector::reserve - Allocates elements for vector to ensure a minimum // size, preserving its contents if the new size is // larger than existing size. // // vector::push_back - Appends (inserts) an element to the end of a // vector, allocating memory for it if necessary. // ////////////////////////////////////////////////////////////////////// // The debugger cannot handle symbols more than 255 characters long. // The C++ Standard Library often creates symbols longer than that. // The warning can be disabled: //#pragma warning(disable:4786) #include #include #include using namespace std; template void print(const string& s, const C& c) < cout cout void printvstats(const vector& v) < cout << " the vector's size is: " << v.size() << endl; cout << " the vector's capacity is: " << v.capacity() << endl; cout << " the vector's maximum size is: " << v.max_size() int main() < // declare a vector that begins with 0 elements. vectorv; // Show statistics about vector. cout coutreverse_iterator
Тип, предоставляющий итератор произвольного доступа, который может читать или изменять любой элемент в обратном векторе.
typedef std::reverse_iterator reverse_iterator;Замечания
Тип reverse_iterator используется для последовательного прохождения через вектор в обратную сторону.
Пример
Пример см. в примере rbegin .
shrink_to_fit
Удаляет лишнюю емкость.
void shrink_to_fit();Пример
// vector_shrink_to_fit.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; //vector ::iterator Iter; v1.push_back( 1 ); coutCurrent capacity of v1 = 1 Current capacity of v1 = 20 Current capacity of v1 = 1size
Возвращает количество элементов в векторе.
size_type size() const;Возвращаемое значение
Текущая длина вектора.
Пример
// vector_size.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1; vector ::size_type i; v1.push_back( 1 ); i = v1.size( ); coutVector length is 1. Vector length is now 2.size_type
Тип, считающий количество элементов в векторе.
typedef typename Allocator::size_type size_type;Пример
Пример см. в примере capacity .
swap
Меняет местами элементы двух векторов.
void swap( vector& right); friend void swap( vector& left, vector& right);Параметры
right
Вектор, предоставляющий элементы для замены. Или вектор, элементы которого необходимо обмениваться элементами в векторе left .left
Вектор, элементы которого необходимо обмениваться элементами в векторе right .Пример
// vector_swap.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector v1, v2; v1.push_back( 1 ); v1.push_back( 2 ); v1.push_back( 3 ); v2.push_back( 10 ); v2.push_back( 20 ); coutThe number of elements in v1 = 3 The number of elements in v2 = 2 The number of elements in v1 = 2 The number of elements in v2 = 3value_type
Тип, представляющий тип данных, хранящихся в векторе.
typedef typename Allocator::value_type value_type;Замечания
value_type является синонимом для параметра-шаблона Type .
Пример
// vector_value_type.cpp // compile with: /EHsc #include #include int main( ) < using namespace std; vector::value_type AnInt; AnInt = 44; coutvector
Создает вектор. Перегрузки создают вектор определенного размера или элементы определенного значения. Или, как копия всех или части другого вектора. Некоторые перегрузки также позволяют указать используемый распределитель.
vector(); explicit vector(const Allocator& allocator); explicit vector(size_type count); vector(size_type count, const Type& value); vector(size_type count, const Type& value, const Allocator& allocator); vector(const vector& source); vector(vector&& source); vector(initializer_list init_list, const Allocator& allocator); template vector(InputIterator first, InputIterator last); template vector(InputIterator first, InputIterator last, const Allocator& allocator);Параметры
allocator
Класс распределителя для использования с данным объектом. get_allocator возвращает класс распределителя для объекта.count
Количество элементов в создаваемом векторе.value
Значение элементов в создаваемом векторе.source
Вектор, для которого создаваемый вектор станет копией.first
Положение первого элемента в диапазоне копируемых элементов.last
Положение первого элемента за пределами диапазона копируемых элементов.init_list
Содержащий initializer_list элементы для копирования.Замечания
Все конструкторы хранят объект распределителя ( allocator ) и инициализировать вектор.
Первые два конструктора определяют пустой исходный вектор. Второй конструктор явно указывает тип распределителя ( allocator ) для использования.
Третий конструктор задает повторение указанного числа ( count ) элементов со значением по умолчанию для класса Type .
Четвертый и пятый конструкторы указывают повторение ( count ) элементов значения value .
Шестой конструктор задает копию вектора source .
Седьмой конструктор перемещает вектор source .
Восьмой конструктор использует initializer_list, чтобы указать элементы.
Девятый и десятый конструкторы копируют диапазон [ first , last ) вектора.
Пример
// vector_ctor.cpp // compile with: /EHsc #include #include int main() < using namespace std; vector ::iterator v1_Iter, v2_Iter, v3_Iter, v4_Iter, v5_Iter, v6_Iter; // Create an empty vector v0 vector v0; // Create a vector v1 with 3 elements of default value 0 vector v1(3); // Create a vector v2 with 5 elements of value 2 vector v2(5, 2); // Create a vector v3 with 3 elements of value 1 and with the allocator // of vector v2 vector v3(3, 1, v2.get_allocator()); // Create a copy, vector v4, of vector v2 vector v4(v2); // Create a new temporary vector for demonstrating copying ranges vector v5(5); for (auto i : v5) < v5[i] = i; >// Create a vector v6 by copying the range v5[ first, last) vector v6(v5.begin() + 1, v5.begin() + 3); cout cout cout cout cout cout cout << endl; // Move vector v2 to vector v7 vector v7(move(v2)); vector ::iterator v7_Iter; cout cout << endl; cout << "v8 ="; vectorv8 < < 1, 2, 3, 4 >>; for (auto& v : v8) < cout coutv1 = 0 0 0 v2 = 2 2 2 2 2 v3 = 1 1 1 v4 = 2 2 2 2 2 v5 = 0 0 0 0 0 v6 = 0 0 v7 = 2 2 2 2 2 v8 = 1 2 3 4Перевод "energy action plan" на русский
Ghana, one of the first countries to partner with the initiative, has developed a national energy action plan to support capacity development and innovative financing.
Гана, одна из первых стран, присоединившихся к инициативе, разработала национальный план действий в области энергетики для поддержки развития потенциала и инновационного финансирования.
Energy Action Plan of Municipality of Agios Athanasios (2012)
План действий в области энергетики муниципалитета Агиос Афанасиос (2012)Each Member State is required to submit a National Renewable Energy Action Plan (NREAP) to the European Commission by 30 June 2010.
Национальный план действие по возобновляемым источникам энергии (А National Renewable Energy Action Plan (NREAP)) является Национальным планом действий по возобновляемой энергии, о котором все государства-члены Европейского союза обязаны были уведомить Европейскую комиссию к 30 июня 2010 года.
A National Renewable Energy Action Plan (NREAP) is a national action plan on renewable energy that all Member States of the European Union were obliged to notify to the European Commission by 30 June.
Национальный план действие по возобновляемым источникам энергии (А National Renewable Energy Action Plan (NREAP)) является Национальным планом действий по возобновляемой энергии, о котором все государства-члены Европейского союза обязаны были уведомить Европейскую комиссию к 30 июня 2010 года.
HUD has adopted a wide-ranging energy action plan for improving energy efficiency in all program areas.
Министерством энергетики РФ был разработан комплексный план действий по повышению эффективности использования энергетических ресурсов во всех секторах экономики.
To this end, each CP is expected to publish a forecast document six months before its national renewable energy action plan is due.
Предполагается, что с этой целью каждая ДС будет публиковать документ с прогнозом за шесть месяцев до появления ее национального плана действий в области возобновляемых источников энергии.
The Danish government presented its proposal for a green energy action plan "Our Energy" today.
Новое датское правительство обнародовало план развития энергетики - "Our future energy".They should establish a national renewable energy action plan including information on sectoral targets, while having in mind that there are different uses of biomass and therefore it is essential to mobilise new biomass resources.
Они должны разработать национальный план действий в области возобновляемых источников энергии, включая информацию о плановых заданиях для секторов, помня при этом, что есть разные способы использования биомассы, и поэтому важно мобилизовать новые ресурсы биомассы.
They should establish a national renewable energy action plan including information on sectoral targets, while having in mind that there are different uses of biomass and therefore it is essential to mobilise new biomass resources.
Им следует выработать государственный план действий по использованию энергии из возобновляемых источников, включающий в себя информацию о целях по секторам, учитывая разницу потребности в биомассе и необходимость привлечения ресурсов.
Nasalyk assured that Ukraine saw Denmark as a reliable and strategic partner as this country already in 2015 had achieved the goal of its national renewable energy action plan until 2020, namely, 30% of clean energy in final energy consumption.
Насалик заверил, что Украина видит в Дании надежного и стратегического партнера, ведь эта страна уже в 2015 году достигла цели своего Национального плана действий по восстанавливаемой энергетике до 2020 года, а именно - 30% чистой энергии в конечном энергопотреблении.
Thus, according to our commitments to the European Union, we have developed and adopted a national renewable energy action plan by 2020 and have set-up an ambitious goal to achieve 11% share of green energy in total energy consumption.
Так, согласно взятых обязательств перед Европейским Союзом, мы разработали и приняли Национальный план действий по возобновляемой энергетике до 2020 года и поставили амбициозную цель: достичь 11% доли «зеленой» энергии в конечном энергопотреблении.
In practice, each city signatory develops a sustainable energy action plan, which includes a number of measures to reduce consumption of resources, while maintaining comfortable living standards for local residents.
На практике реализация такой задачи заключается в разработке каждым городом-подписантом Плана действий по устойчивой энергетике, который включает ряд мероприятий по снижению потребления ресурсов при сохранении комфортности проживания местных жителей.
SEAP (Sustainable energy action plan) is a document developed by authorities in frame of Covenant of Mayors
SEAP (План действий по устойчивому энергетическому развитию) - это документ, разработанный властями в рамках Пакта мэров.