为何无法以该方式解引用二维std::vector的迭代器?
闭岛计数代码的编译错误分析
以下是闭岛计数问题的朴素实现代码:输入由1(水域)和0(陆地)组成的二维std::vector到closedIsland函数,目标是统计被水域环绕的“闭岛”数量。代码中使用迭代器遍历vector,辅助函数checkSurroundings用于场景逻辑检查,但其中一处代码引发编译错误。
#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) //error here is_surrounded = true; break; //other cases follow } break; //other cases follow } } 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)
错误原因分析
你预期的逻辑方向是对的,但这里栽在了C++运算符优先级上:
col_it是std::vector<std::vector<int>>::iterator类型,col_it[index_row]等价于*(col_it + index_row),会直接返回第index_row个std::vector<int>对象(而非你想的先解引用col_it得到当前vector再取元素)。- 随后你对这个vector对象用
*解引用,自然会报错——vector不是指针,不能直接解引用。
正确的写法应该是先解引用迭代器拿到当前的std::vector<int>,再用[]访问元素:
(*col_it)[index_row] == 1
或者更安全的写法(自动检查越界):
col_it->at(index_row) == 1
额外代码问题提示
除了这个编译错误,代码还有几个逻辑/语法问题需要修正:
for循环里的column_it+1和row_it+1不会改变迭代器的位置,应该改成column_it++和row_it++,否则会陷入死循环。std::distance(column_it, grid.end())得到的是从当前列到末尾的元素数,而非当前列的索引,正确索引应为std::distance(grid.begin(), column_it);行索引同理,需改为std::distance(column_it->begin(), row_it),否则索引值会完全反转。
内容的提问来源于stack exchange,提问作者Blargian
相关产品推荐
相关产品推荐

