Конкатенация двух std::vector в C++: как объединить векторы?
Правильный способ: использование метода insert или алгоритмов std::copy/std::move
В C++ нет оператора + для std::vector, но есть несколько элегантных способов конкатенации. Самый простой и интуитивный — использовать метод insert у целевого вектора. Вот классическое решение:
#include <vector>
#include <iterator> // для std::back_inserter (опционально)
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {4, 5, 6};
// Способ 1: через insert (рекомендуется для новичков)
std::vector<int> vec3 = vec1; // копируем первый вектор
vec3.insert(vec3.end(), vec2.begin(), vec2.end()); // вставляем второй в конец
// Результат: vec3 = {1, 2, 3, 4, 5, 6}
Этот код сначала создаёт копию vec1, а затем вставляет все элементы vec2 в конец. Метод insert принимает три аргумента: позицию (итератор на конец), начало и конец диапазона для вставки.
Альтернативный подход через std::copy с std::back_inserter
Если вы предпочитаете алгоритмы STL, можно использовать std::copy:
#include <algorithm> // для std::copy
std::vector<int> vec3;
vec3.reserve(vec1.size() + vec2.size()); // оптимизация: выделяем память заранее
vec3.insert(vec3.end(), vec1.begin(), vec1.end());
vec3.insert(vec3.end(), vec2.begin(), vec2.end());
// Или с std::copy:
// std::copy(vec1.begin(), vec1.end(), std::back_inserter(vec3));
// std::copy(vec2.begin(), vec2.end(), std::back_inserter(vec3));
Обратите внимание на вызов reserve. Он выделяет память сразу под итоговый размер, избегая многократных перераспределений. Это повышает производительность для больших векторов.
Современный C++17: std::merge для отсортированных векторов
Если оба вектора отсортированы, и вы хотите получить отсортированный результат, используйте std::merge:
#include <algorithm>
std::vector<int> vec1 = {1, 3, 5};
std::vector<int> vec2 = {2, 4, 6};
std::vector<int> vec3(vec1.size() + vec2.size());
std::merge(vec1.begin(), vec1.end(),
vec2.begin(), vec2.end(),
vec3.begin());
// vec3 = {1, 2, 3, 4, 5, 6}
std::merge требует предварительного выделения памяти (как в примере) и работает за линейное время O(n+m).
Что выбрать?
- Если вам нужно просто объединить два вектора — используйте
insertсreserve. Это читаемо и эффективно. - Если вы работаете с большими данными и хотите избежать копирования — используйте
std::move(см. альтернативный ответ). - Если векторы отсортированы —
std::mergeдаст отсортированный результат за один проход.
Главное — не пытайтесь перегрузить оператор + для векторов, это нарушит принципы работы стандартной библиотеки. Используйте готовые методы и алгоритмы STL — они оптимизированы и безопасны.
Способ с перемещением (C++11 и новее)
Если исходные векторы больше не нужны, и вы хотите избежать лишних копирований, используйте семантику перемещения. Это особенно эффективно для больших объектов (например, std::vector<std::string>).
#include <vector>
#include <utility> // для std::move
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = {4, 5, 6};
// Перемещаем vec2 в vec1 (vec2 станет пустым!)
vec1.insert(vec1.end(),
std::make_move_iterator(vec2.begin()),
std::make_move_iterator(vec2.end()));
// vec1 = {1, 2, 3, 4, 5, 6}
// vec2 теперь пуст или в неопределённом состоянии
Здесь std::make_move_iterator создаёт итератор, который при разыменовании использует std::move, что позволяет перемещать элементы вместо их копирования. После этой операции vec2 остаётся в "перемещённом" состоянии — его можно уничтожить или присвоить ему новое значение, но использовать его содержимое больше нельзя.
Важно: Этот способ подходит только если вам не нужны исходные данные. Для простых типов (int, double) выигрыша в производительности не будет, но для сложных объектов с динамическим выделением памяти (строки, контейнеры) перемещение может дать значительный прирост скорости.
Также можно полностью переместить второй вектор в первый, если он пуст:
std::vector<int> vec3 = std::move(vec1); // vec1 теперь пуст
vec3.insert(vec3.end(), vec2.begin(), vec2.end());
Выбирайте этот подход, когда память и производительность критичны, а исходные данные можно безопасно "уничтожить".