微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用于包含不同元素的 2 个向量的单个迭代器 (c++)

如何解决用于包含不同元素的 2 个向量的单个迭代器 (c++)

我有两个相同长度的向量。其中之一持有 double 的向量:

std::vector<std::vector<double>> A;

第二个是双打

std::vector<double> B;

“相同长度”是指 A 包含的 double 向量与 B 包含的 double 向量一样多。 我想同时用一个迭代器遍历它们。我有一种感觉,我需要创建一个类来做到这一点。类似的东西

std::vector<vector<double>>::iterator iter = A.begin();
for (A= iter.begin(); iter != A.end(); iter++)
{
 (*iter).A // I access an element of A std::vector<double>
 (*iter).B // I access an element of B (double)
}

我检查了一个类似的问题,这个问题非常接近我想要做的:

enter image description here

但在我的例子中,迭代器有两种不同的类型,分别是 std::vector<vector<double>>::iteratorvector<double>::iterator,所以这个问题的解决方案不起作用,但我想它很接近。

我该怎么做?最好的方法是什么?

解决方法

原则上,您可以编写一个具有 firstsecond 的自定义迭代器,分别引用 AB 的元素。然而,自定义迭代器并不简单。更简单的替代方法是使用普通的基于旧索引的循环:

for (size_t i = 0; i < A.size() && i < B.size(); ++i)
{
     A[i]; // I access an element of A std::vector<double>
     B[i]; // I access an element of B (double)
}

或者使用两个迭代器

auto itA = A.begin();
auto itB = B.begin();
for ( ; itA != A.end() && itB != B.end(); ++itA,++itB) {
    //...
}

您可能还对来自 boost 的 zip_iterator 或来自 range-v3 库的 view::zip 感兴趣:

#include <iostream>
#include <vector>
#include <range/v3/view.hpp>    

int main() {
    std::vector<int> A{1,2,3,4,5};
    std::vector<double> B{1.2,3.4,5.6,7.8,9.1};
    for (const auto& [a,b] : ranges::view::zip(A,B)) { 
        std::cout << a << "  " << b << "\n";
    }
}

Live Demo

标准范围库基于 Nieblers 范围,但到目前为止 zip 还没有进入标准库。如果我理解正确的话,C++23 是可以预期的。


PS:请注意,您的 for (A= iter.begin(); iter != A.end(); iter++) 可以被视为“老式”。由于 C++11 有 range based for loops,可以让您从头到尾迭代容器的元素。他们更进一步,还对您隐藏了迭代器(它们仍然存在),以减少拼写错误的机会。虽然,就像基于迭代器的循环不如基于索引的循环灵活一样,基于范围的循环比基于迭代器的循环灵活一些。它们只允许您从 begin 迭代到 end

for (const auto& a : A) { 
    a; // a is a const reference to element in A
}

我只是为了完整性才提到这一点,对于基于范围的循环,将两个迭代器“压缩”为一个既不简单,也不复杂,就像旧的基于迭代器的循环一样。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。