迭代一个非常非常长的 std::vector 问题

vel*_*s14 1 c++ for-loop stdvector

我有一个std::vector<std::tuple<int, int>>能够容纳很多潜在元素的东西。

我事先不知道它会有多少个元素。这取决于我如何运行代码(使用什么输入参数)。

我想迭代这个向量。

目前,我正在做:

for (long long int idx = 0; idx <= (vec.size() - 1); idx++) {
    do_something(vec[idx]);
}
Run Code Online (Sandbox Code Playgroud)

这会产生警告: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::tuple<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]

从SO中,我知道vec.size()返回 a std::vector<std::tuple<int, int> >::size_type,我知道它可能与以下内容不同size_t/sf/answers/1996006421/

我的问题是:我该如何编写 for 循环来迭代向量的所有元素,而不发出警告?

例如, anint是不够的,我确信向量将容纳多个65535元素。

另外,long unsigned int编译器告诉我.size()返回的内容可能不足以容纳我的向量的所有元素:来自https://en.cppreference.com/w/cpp/language/types,它似乎可以上升至4,294,967,295仅。

根据谷歌的说法,4 294 967 295 * 8 字节 = 34.3597384 GB,是的,我的 RAM 确实比这个多(我在一个 HPC 服务器上,每个节点有 128 GB 的 RAM)。

这个问题也可以仅针对整数向量提出,上面的乘法将被执行为 4 294 967 295 * 4 字节......

谢谢你!

Mik*_*ail 10

更喜欢基于范围的:

for (const auto& elem : vec) {
    do_something(elem);
}
Run Code Online (Sandbox Code Playgroud)

在底层,它使用指向向量元素的指针进行操作。如果可以指向一个元素,则该循环将访问该元素。如果无法指向某个元素,则无论如何都无法将其存储在向量中。


Vla*_*cow 6

编译器发出警告是因为在这个 for 循环中

for (long long int idx = 0; idx <= (vec.size() - 1); idx++) {
Run Code Online (Sandbox Code Playgroud)

在循环条件中,比较有符号和无符号整数类型的值。至少你可以写例如

for ( unsigned long long int idx = 0; idx < vec.size(); idx++) {
Run Code Online (Sandbox Code Playgroud)

不过,如果您需要使用索引来访问向量的元素,那么最好编写

for ( decltype( vec )::size_type idx = 0; idx < vec.size(); idx++ ) 
{
    do_something(vec[idx]);
}
Run Code Online (Sandbox Code Playgroud)

否则你可以使用基于范围的 for 循环,例如

for ( const auto &elem : vec )
{
        do_something( elem );
}
Run Code Online (Sandbox Code Playgroud)


Nel*_*eal 5

我明白vec.size()返回一个std::vector<std::tuple<int, int>>::size_type

所以使用它:

for (decltype(vec.size()) i = 0; i < vec.size(); ++i) {
    do_something(vec[i]);
}
Run Code Online (Sandbox Code Playgroud)

您还可以创建 am 显式类型别名:

using IndexType = std::vector<std::tuple<int, int>>::size_type;
for (IndexType i = 0; i < vec.size(); ++i) { ... }
Run Code Online (Sandbox Code Playgroud)

或者使用基于范围的 for 循环,可选地在侧面添加索引:

decltype(vec.size()) i = 0;
for (auto& value : vec) { // may be `auto const&` or even just `auto`
    do_something(value, i);
    ++i;
}
Run Code Online (Sandbox Code Playgroud)

或者直接使用迭代器:

for (auto it = vec.begin(); it != vec.end(); ++it) {
    // std::distance is constant-time with std::vector iterators (basically just `it - vec.begin()`)
    auto i = std::distance(vec.begin(), it);
    do_something(*it, i);
}
Run Code Online (Sandbox Code Playgroud)

演示