3 回答
TA贡献1835条经验 获得超7个赞
但是:我会遍历索引。但是不使用经典for循环,而是使用基于范围for的索引循环:
for(unsigned i : indices(containerA)) {
containerA[i] = containerB[i];
}
indices是一个简单的包装函数,它返回索引的(延迟计算)范围。由于实现虽然简单,但将其发布到此处有点太长,因此可以在GitHub上找到实现。
此代码与使用手动经典循环一样有效for。
如果这种模式经常出现在您的数据中,请考虑使用具有zip两个序列并产生一系列元组(对应于成对的元素)的另一种模式:
for (auto& [a, b] : zip(containerA, containerB)) {
a = b;
}
的实现zip留给读者练习,但是从实现开始很容易indices。
(在C ++ 17之前,您必须编写以下代码:)
for (auto items&& : zip(containerA, containerB))
get<0>(items) = get<1>(items);
TA贡献2019条经验 获得超9个赞
对于您的特定示例,只需使用
std::copy_n(contB.begin(), contA.size(), contA.begin())
对于更一般的情况,您可以使用Boost.Iterator的zip_iterator,它具有一个小的函数,使其可以在基于范围的for循环中使用。在大多数情况下,这将起作用:
template<class... Conts>
auto zip_range(Conts&... conts)
-> decltype(boost::make_iterator_range(
boost::make_zip_iterator(boost::make_tuple(conts.begin()...)),
boost::make_zip_iterator(boost::make_tuple(conts.end()...))))
{
return {boost::make_zip_iterator(boost::make_tuple(conts.begin()...)),
boost::make_zip_iterator(boost::make_tuple(conts.end()...))};
}
// ...
for(auto&& t : zip_range(contA, contB))
std::cout << t.get<0>() << " : " << t.get<1>() << "\n";
现场示例。
然而,对于全面的通用性,你可能想要的东西更像是这样,这将正常工作,数组和用户定义的类型没有成员begin()/ end()但这样做有begin/ end功能在他们的命名空间。同样,这将允许用户const通过zip_c...功能专门访问。
而且,如果您像我一样倡导漂亮的错误消息,那么您可能需要this,它检查是否将任何临时容器传递给任何zip_...函数,如果是,则打印一条漂亮的错误消息。
TA贡献1830条经验 获得超3个赞
我不知道为什么没人提到这个:
auto ItA = VectorA.begin();
auto ItB = VectorB.begin();
while(ItA != VectorA.end() || ItB != VectorB.end())
{
if(ItA != VectorA.end())
{
++ItA;
}
if(ItB != VectorB.end())
{
++ItB;
}
}
PS:如果容器大小不匹配,则必须将代码放入if语句内。
- 3 回答
- 0 关注
- 1544 浏览
添加回答
举报