我如何连接两个std::向量?
当前回答
如果你正在寻找的是在创建后将一个向量附加到另一个向量的方法,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
其他回答
这个解决方案可能有点复杂,但助推范围也有一些其他的好处。
#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)这样的东西,这可能是合理的。
我已经实现了这个函数,它连接任何数量的容器,从右值引用移动和复制
namespace internal {
// Implementation detail of Concatenate, appends to a pre-reserved vector, copying or moving if
// appropriate
template<typename Target, typename Head, typename... Tail>
void AppendNoReserve(Target* target, Head&& head, Tail&&... tail) {
// Currently, require each homogenous inputs. If there is demand, we could probably implement a
// version that outputs a vector whose value_type is the common_type of all the containers
// passed to it, and call it ConvertingConcatenate.
static_assert(
std::is_same_v<
typename std::decay_t<Target>::value_type,
typename std::decay_t<Head>::value_type>,
"Concatenate requires each container passed to it to have the same value_type");
if constexpr (std::is_lvalue_reference_v<Head>) {
std::copy(head.begin(), head.end(), std::back_inserter(*target));
} else {
std::move(head.begin(), head.end(), std::back_inserter(*target));
}
if constexpr (sizeof...(Tail) > 0) {
AppendNoReserve(target, std::forward<Tail>(tail)...);
}
}
template<typename Head, typename... Tail>
size_t TotalSize(const Head& head, const Tail&... tail) {
if constexpr (sizeof...(Tail) > 0) {
return head.size() + TotalSize(tail...);
} else {
return head.size();
}
}
} // namespace internal
/// Concatenate the provided containers into a single vector. Moves from rvalue references, copies
/// otherwise.
template<typename Head, typename... Tail>
auto Concatenate(Head&& head, Tail&&... tail) {
size_t totalSize = internal::TotalSize(head, tail...);
std::vector<typename std::decay_t<Head>::value_type> result;
result.reserve(totalSize);
internal::AppendNoReserve(&result, std::forward<Head>(head), std::forward<Tail>(tail)...);
return result;
}
如果您的目标只是为了只读目的而在值的范围内迭代,另一种替代方法是将两个向量围绕一个代理(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”实现以及优缺点。
如果希望能够简洁地连接向量,可以重载+=运算符。
template <typename T>
std::vector<T>& operator +=(std::vector<T>& vector1, const std::vector<T>& vector2) {
vector1.insert(vector1.end(), vector2.begin(), vector2.end());
return vector1;
}
然后你可以这样调用它:
vector1 += vector2;
试着创建两个向量,把第二个向量和第一个向量相加, 代码:
std::vector<int> v1{1,2,3};
std::vector<int> v2{4,5};
for(int i = 0; i<v2.size();i++)
{
v1.push_back(v2[i]);
}
v1:1 2 3。
描述:
当i int不是v2大小时,回推元素,在v1向量中索引i。