为什么我无法以这种方式取消引用二维向量的迭代器?

huangapple go评论65阅读模式
英文:

Why am I unable to dereference an iterator of a 2D vector in this way?

问题

以下是代码的翻译部分,没有包含问题或其他信息:

以下代码是解决问题的一个天真实现,其中2D矢量中的1和0被输入到名为`closedIsland`的某个函数中,其中某些列和行中的1表示水,0表示陆地。该算法的目的是找到被水包围的“封闭岛屿”的数量,这些岛屿是被水包围的陆地片段。我正在使用迭代器来遍历矢量,并编写了一个名为`checkSurroundings`的辅助函数,以实现一些特定情况的逻辑检查。出于简洁起见,我仅保留了一个案例。正是在这个函数中发生了错误。

```cpp
#include <vector>

bool checkSurroundings(std::vector<std::vector<int>>::iterator col_it, std::vector<int>::iterator row_it, int index_column, int index_row, int max_row_size, int max_col_size) {
    bool is_surrounded = false;
    switch (index_column) {
        case 0:
            col_it++;
            switch (index_row) {
                case 0:
                    if (*(row_it + 1) == 1 && (*col_it)[index_row] == 1) //错误在这里
                        is_surrounded = true;
                    break;
                //其他情况依次类推
            }
            break;
        //其他情况依次类推
    }
}

int closedIsland(std::vector<std::vector<int>>& grid) {
    int max_column_size = grid.size();
    int max_row_size = grid[0].size();
    int closed_island_count = 0;
    bool is_surrounded = false;

    for (std::vector<std::vector<int>>::iterator column_it = grid.begin(); column_it != grid.end(); column_it + 1) {
        for (std::vector<int>::iterator row_it = column_it->begin(); row_it != column_it->end(); row_it + 1) {
            auto index_column = std::distance(column_it, grid.end());
            auto index_row = std::distance(row_it, column_it->end());

            if (*row_it == 0) {
                is_surrounded = checkSurroundings(column_it, row_it, index_column, index_row, max_row_size, max_column_size);
                if (is_surrounded)
                    closed_island_count++;
            }
        }
    }
    return closed_island_count;
}

上面的代码能够编译(除了错误部分)使用g++ -std=c++17

我遇到了以下错误:

error: indirection requires pointer operand ('std::vector<int, std::allocator>' invalid)
if (*(row_it + 1) == 1 && (*col_it)[index_row] == 1)

我原本期望这样的逻辑会起作用:col_it是一个vector<vector<int>>::iterator类型,因此对迭代器进行解引用*(col_it)应该给我vector<vector<int>>本身,通过使用[]符号,我应该能够访问内部的向量。为什么在这种情况下不起作用?

英文:

The following code is a naive implementation of a solution to a problem in which a 2D vector of 1's and 0's are inputted to some function closedIsland where 1's in some column and row represent water and 0's represent land. The aim of the algorithm is to find the number of 'closed islands' which are pieces of land surrounded by water. I am using iterators to loop over the vector and I have written a helper function called checkSurroundings to implement some logic checks for specific cases. For brevity sake, I have excluded all but one of the cases. It is in this function which my error occurs.

#include &lt;vector&gt;
bool checkSurroundings(std::vector&lt;std::vector&lt;int&gt;&gt;::iterator col_it,std::vector&lt;int&gt;::iterator row_it, int index_column, int index_row, int max_row_size, int max_col_size){
bool is_surrounded = false; 
switch(index_column){
case 0: 
col_it++; 
switch(index_row){
case 0:
if(*(row_it+1)==1 &amp;&amp; *(col_it)[index_row]==1) //error here
is_surrounded = true; 
break;
//other cases follow
}
break;
//other cases follow
}
}
int closedIsland(std::vector&lt;std::vector&lt;int&gt;&gt;&amp; grid) {
int max_column_size = grid.size(); 
int max_row_size = grid[0].size(); 
int closed_island_count = 0; 
bool is_surrounded = false;
for(std::vector&lt;std::vector&lt;int&gt;&gt;::iterator column_it = grid.begin(); column_it!=grid.end(); column_it+1){
for(std::vector&lt;int&gt;::iterator row_it = column_it-&gt;begin(); row_it!= column_it-&gt;end(); row_it+1){
auto index_column = std::distance(column_it,grid.end());
auto index_row = std::distance(row_it,column_it-&gt;end());
if(*row_it == 0){
is_surrounded = checkSurroundings(column_it,row_it,index_column,index_row,max_row_size,max_column_size); 
if(is_surrounded)
closed_island_count++;
}
}
}
return closed_island_count; 
}

The code above compiles (apart from the error) using g++ -std=c++17

I am running into the following error:

> error: indirection requires pointer operand ('std::vector<int,
> std::allocator<int>>' invalid)
> if(*(row_it+1)==1 && *(col_it)[index_row]==1)

I was expecting this to work by the following logic: col_it is a vector&lt;vector&lt;int&gt;&gt;::iterator type so dereferncing the iterator *(col_it) should give me the vector&lt;vector&lt;int&gt;&gt; itself and by using [] notation I should be able to access the inner vector. Why does this not work in this case?

答案1

得分: 3

这一切都归结于运算符优先级:由于下标运算符([])的优先级高于一元*运算符,表达式

*(col_it)[index_row]

被解释为

*(col_it[index_row])

而不是

(*col_it)[index_row]

。对于类型为 vector<vector<int>>::iterator 的表达式应用下标运算符会产生对 vector<int> 的引用,而对于这种类型的表达式,一元*运算符未实现,导致了观察到的编译器错误。

英文:

It all comes down to operator precedence: Since the subscript operator ([]) has a higher precedence than the unary * operator, the expression

*(col_it)[index_row]

is evaluated as

*(col_it[index_row])

, not as

(*col_it)[index_row]

. The subscript operator applied to a expression of type vector&lt;vector&lt;int&gt;&gt;::iterator yields a reference to vector&lt;int&gt; and for an expression of this type the unary * operator is not implemented resulting in the compiler error observed.

huangapple
  • 本文由 发表于 2023年4月7日 01:01:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75952016.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定