我如何连接两个std::向量?
当前回答
你可以为+操作符准备自己的模板:
template <typename T>
inline T operator+(const T & a, const T & b)
{
T res = a;
res.insert(res.end(), b.begin(), b.end());
return res;
}
接下来,使用+:
vector<int> a{1, 2, 3, 4};
vector<int> b{5, 6, 7, 8};
for (auto x: a + b)
cout << x << " ";
cout << endl;
这个例子给出了输出:
1 2 3 4 5 6 7 8
其他回答
你可以为+操作符准备自己的模板:
template <typename T>
inline T operator+(const T & a, const T & b)
{
T res = a;
res.insert(res.end(), b.begin(), b.end());
return res;
}
接下来,使用+:
vector<int> a{1, 2, 3, 4};
vector<int> b{5, 6, 7, 8};
for (auto x: a + b)
cout << x << " ";
cout << endl;
这个例子给出了输出:
1 2 3 4 5 6 7 8
如果您的目标只是为了只读目的而在值的范围内迭代,另一种替代方法是将两个向量围绕一个代理(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”实现以及优缺点。
您可以使用预先实现的STL算法,使用用于多态类型使用的模板来实现它。
#include <iostream>
#include <vector>
#include <algorithm>
template<typename T>
void concat(std::vector<T>& valuesa, std::vector<T>& valuesb){
for_each(valuesb.begin(), valuesb.end(), [&](int value){ valuesa.push_back(value);});
}
int main()
{
std::vector<int> values_p={1,2,3,4,5};
std::vector<int> values_s={6,7};
concat(values_p, values_s);
for(auto& it : values_p){
std::cout<<it<<std::endl;
}
return 0;
}
如果不想进一步使用第二个向量,可以清除它(clear()方法)。
对于range v3,你可能会有一个惰性连接:
ranges::view::concat(v1, v2)
演示。
如果你正在使用c++ 11,并且希望移动元素而不仅仅是复制它们,你可以使用std::move_iterator和insert(或copy):
#include <vector>
#include <iostream>
#include <iterator>
int main(int argc, char** argv) {
std::vector<int> dest{1,2,3,4,5};
std::vector<int> src{6,7,8,9,10};
// Move elements from src to dest.
// src is left in undefined but safe-to-destruct state.
dest.insert(
dest.end(),
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end())
);
// Print out concatenated vector.
std::copy(
dest.begin(),
dest.end(),
std::ostream_iterator<int>(std::cout, "\n")
);
return 0;
}
对于int类型的例子来说,这并不会更有效,因为移动它们并不比复制它们更有效,但对于具有优化移动的数据结构,它可以避免复制不必要的状态:
#include <vector>
#include <iostream>
#include <iterator>
int main(int argc, char** argv) {
std::vector<std::vector<int>> dest{{1,2,3,4,5}, {3,4}};
std::vector<std::vector<int>> src{{6,7,8,9,10}};
// Move elements from src to dest.
// src is left in undefined but safe-to-destruct state.
dest.insert(
dest.end(),
std::make_move_iterator(src.begin()),
std::make_move_iterator(src.end())
);
return 0;
}
移动之后,src的元素处于未定义但可以安全销毁的状态,它之前的元素被直接转移到dest的新元素中。