我应该如何拼接两个std::vector
?
我实现了这个函数,它可以连接任意数量的容器,从rvalue引用移动并复制其他情况。
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;
}
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {11, 12, 13, 14, 15};
copy(v2.begin(), v2.end(), back_inserter(v1));
这个解决方案可能有点复杂,但是 boost-range
还有其他一些不错的东西可以提供。
#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
组合起来并迭代进行某些操作。在这种情况下,有一个非常简单的join
函数。
#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)
这样的东西,这可能是合理的。vector::insert
是您最好的选择,因为已经有多次回答了这个问题,例如:vector<int> first = {13};
const vector<int> second = {42};
first.insert(first.end(), second.cbegin(), second.cend());
遗憾的是,没有办法构造一个const vector<int>
,就像上面所说,你必须先构造然后再insert
。
如果您实际上要寻找的是一个容器来保存这两个vector<int>
的连接,那么可能有更好的选择,如果:
vector
包含原始类型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://dev59.com/jW455IYBdhLWcg3wD_6Z#35558008
如果您需要此代码的实时示例,请参见此处:http://ideone.com/7Iww3I
我尝试使用C++17解决这个任务,而不使用rangesV3库。在阅读了一些关于此主题的帖子后,我得出了这个解决方案:
namespace algorithms
{
/*!
* \brief Wraps incoming element and move/or copy the elements from one to another.
* \example return (wrapped_plus(container) + ...).value
*/
template <class T>
struct wrapped_plus {
using value_type = T;
value_type value;
wrapped_plus(value_type&& in) : value(std::move(in)) {}
wrapped_plus(const value_type& in) : value(in) {}
wrapped_plus operator+(const wrapped_plus& in)
{
std::copy(std::begin(in.value), std::end(in.value), std::back_inserter(value));
return *this;
}
wrapped_plus operator+(wrapped_plus&& in)
{
std::move(std::make_move_iterator(std::begin(in.value)), std::make_move_iterator(std::end(in.value)), std::back_inserter(value));
return *this;
}
};
/*!
* \brief Merge 2 or more STL containers with same type.
* \example merge(container,container,container)
*/
template <typename... Containers>
static inline auto merge(Containers&&... c)
{
return (wrapped_plus(c) + ...).value;
}
} // namespace algorithms
int main(int argc, char** argv)
{
std::vector<int> dest{1,2,3,4,5};
std::vector<int> src{6,7,8,9,10};
auto result = algorithms::merge(dest,src);
return 0;
}
您可以使用预先实现的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()
方法来清除它。使用 for
循环将两个 std::vector
连接成一个 std::vector
。
std::vector <int> v1 {1, 2, 3}; //declare vector1
std::vector <int> v2 {4, 5}; //declare vector2
std::vector <int> suma; //declare vector suma
for(int i = 0; i < v1.size(); i++) //for loop 1
{
suma.push_back(v1[i]);
}
for(int i = 0; i< v2.size(); i++) //for loop 2
{
suma.push_back(v2[i]);
}
for(int i = 0; i < suma.size(); i++) //for loop 3-output
{
std::cout << suma[i];
}
vector<int> concat_vector = vector<int>();
concat_vector.setcapacity(vector_A.size() + vector_B.size());
// Loop for copy elements in two vectors into concat_vector
方法2:通过添加/插入向量B的元素来将向量A进行扩展。
// Loop for insert elements of vector_B into vector_A with insert()
function: vector_A.insert(vector_A .end(), vector_B.cbegin(), vector_B.cend());
std::move_iterator
,以便移动元素而不是复制它们。 (请参阅http://en.cppreference.com/w/cpp/iterator/move_iterator)。 - tmlensetcapacity
?什么是 function:
? - L. F.resize
方法。 - Matthieu H尝试创建两个向量并将第二个向量添加到第一个向量中,代码:
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不等于v2的大小时,在v1向量中将元素插入到索引为i的位置。
a + b
或a.concat(b)
的人吗?也许默认实现会不够优化,但并不需要对每个数组连接都进行微观优化。 - oseiskarforceVector1 + forceVector2
,以便在清晰简明的代码中进行逐项加法。 - Jonathan Lidbeck