我如何连接两个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
其他回答
你应该使用vector::insert
v1.insert(v1.end(), v2.begin(), v2.end());
如果你正在使用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的新元素中。
您可以使用预先实现的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()方法)。
如果希望能够简洁地连接向量,可以重载+=运算符。
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;
我更喜欢前面提到的一个:
a.insert(a.end(), b.begin(), b.end());
但是如果你使用c++ 11,有一个更通用的方法:
a.insert(std::end(a), std::begin(b), std::end(b));
另外,这不是问题的一部分,但建议在追加之前使用reserve以获得更好的性能。如果你把向量和它自己连接起来,如果不保留,它就失败了,所以你总是应该保留。
所以基本上你需要:
template <typename T>
void Append(std::vector<T>& a, const std::vector<T>& b)
{
a.reserve(a.size() + b.size());
a.insert(a.end(), b.begin(), b.end());
}