我如何连接两个std::向量?


当前回答

vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {11, 12, 13, 14, 15};
copy(v2.begin(), v2.end(), back_inserter(v1));

其他回答

这个解决方案可能有点复杂,但助推范围也有一些其他的好处。

#include <iostream>
#include <vector>
#include <boost/range/algorithm/copy.hpp>

int main(int, char**) {
    std::vector<int> a = { 1,2,3 };
    std::vector<int> b = { 4,5,6 };
    boost::copy(b, std::back_inserter(a));
    for (auto& iter : a) {
        std::cout << iter << " ";
    }
    return EXIT_SUCCESS;
}

通常我们的目的是将向量a和b结合起来只是在上面做一些运算。在本例中,有一个可笑的简单连接函数。

#include <iostream>
#include <vector>
#include <boost/range/join.hpp>
#include <boost/range/algorithm/copy.hpp>

int main(int, char**) {
    std::vector<int> a = { 1,2,3 };
    std::vector<int> b = { 4,5,6 };
    std::vector<int> c = { 7,8,9 };
    // Just creates an iterator
    for (auto& iter : boost::join(a, boost::join(b, c))) {
        std::cout << iter << " ";
    }
    std::cout << "\n";
    // Can also be used to create a copy
    std::vector<int> d;
    boost::copy(boost::join(a, boost::join(b, c)), std::back_inserter(d));
    for (auto& iter : d) {
        std::cout << iter << " ";
    }
    return EXIT_SUCCESS;
}

对于较大的向量,这可能是一个优势,因为不需要复制。它还可以用于轻松地将泛化复制到多个容器。

出于某种原因,没有像boost::join(a,b,c)这样的东西,这可能是合理的。

vector1.insert( vector1.end(), vector2.begin(), vector2.end() );

如果您的目标只是为了只读目的而在值的范围内迭代,另一种替代方法是将两个向量围绕一个代理(O(1))而不是复制它们(O(n)),这样它们就会立即被视为单个连续的向量。

std::vector<int> A{ 1, 2, 3, 4, 5};
std::vector<int> B{ 10, 20, 30 };

VecProxy<int> AB(A, B);  // ----> O(1)!

for (size_t i = 0; i < AB.size(); i++)
    std::cout << AB[i] << " ";  // ----> 1 2 3 4 5 10 20 30

请参阅https://stackoverflow.com/a/55838758/2379625了解更多细节,包括“VecProxy”实现以及优缺点。

或者你可以用:

std::copy(source.begin(), source.end(), std::back_inserter(destination));

如果两个向量不包含完全相同类型的内容,则此模式非常有用,因为您可以使用某些内容而不是std::back_inserter来从一种类型转换为另一种类型。

如果你对强异常保证感兴趣(当复制构造函数可以抛出异常时):

template<typename T>
inline void append_copy(std::vector<T>& v1, const std::vector<T>& v2)
{
    const auto orig_v1_size = v1.size();
    v1.reserve(orig_v1_size + v2.size());
    try
    {
        v1.insert(v1.end(), v2.begin(), v2.end());
    }
    catch(...)
    {
        v1.erase(v1.begin() + orig_v1_size, v1.end());
        throw;
    }
}

如果vector元素的move构造函数可以抛出(这是不太可能的,但仍然是),那么具有强保证的类似append_move通常不能实现。