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


当前回答

对于range v3,你可能会有一个惰性连接:

ranges::view::concat(v1, v2)

演示。

其他回答

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

#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)这样的东西,这可能是合理的。

对于提供push_back (string, vector, deque,…)功能的容器:

Std::copy(Std::begin(input), Std::end(input), Std::back_inserter(output))

and

对于提供insert (map, sets)功能的容器:

Std::copy(Std::begin(input), Std::end(input), Std::inserter(output, output.end()))

如果你正在寻找的是在创建后将一个向量附加到另一个向量的方法,vector::insert是你最好的选择,因为已经回答了几次,例如:

vector<int> first = {13};
const vector<int> second = {42};

first.insert(first.end(), second.cbegin(), second.cend());

遗憾的是,没有办法构造一个const vector<int>,就像上面那样,你必须先构造然后插入。


如果你实际上是在寻找一个容器来保存这两个vector<int>s的连接,可能有更好的可用的东西给你,如果:

你的向量包含原语 包含的原语的大小为32位或更小 你需要一个const容器

如果以上都是正确的,我建议使用basic_string,它的char_type匹配vector中包含的原语的大小。你应该在你的代码中包含一个static_assert来验证这些大小保持一致:

static_assert(sizeof(char32_t) == sizeof(int));

有了这一点,你可以这样做:

const u32string concatenation = u32string(first.cbegin(), first.cend()) + u32string(second.cbegin(), second.cend());

要了解更多关于string和vector之间区别的信息,您可以查看这里:https://stackoverflow.com/a/35558008/2642059

有关此代码的实际示例,您可以在这里查看:http://ideone.com/7Iww3I

c++ 17中有一个算法std::merge,当输入向量排序时,它非常容易使用,

下面是例子:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    //DATA
    std::vector<int> v1{2,4,6,8};
    std::vector<int> v2{12,14,16,18};

    //MERGE
    std::vector<int> dst;
    std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));

    //PRINT
    for(auto item:dst)
        std::cout<<item<<" ";

    return 0;
}

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

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通常不能实现。