在std :: list中的end()之后的下一个迭代器

时间:2016-10-30 11:21:06

标签: c++ c++11 iterator stdlist

#include <iostream>
#include <list>
#include <deque>
int main( void )
{
    std::deque< std::deque< int > > integers_lists ;
    const std::list< int > list0 { 1 , 2 , 3 } ;
    for ( auto current = std::next( list0.cbegin() ) 
          ; current != std::next( list0.cend() ) 
          ; ++ current ) integers_lists.emplace_back( list0.cbegin() , current ) ;
    for ( const auto& sub : integers_lists )
    {
        for ( auto each : sub ) std::cout << each << " " ;
        std::cout << "\n" ;
    }
    return 0;
}

在这种情况下,STL是否保证current != std::next( list0.cend() )表达式的正确性。 以及标准中指向的确切位置。

1 个答案:

答案 0 :(得分:3)

std::next( list0.end() )几乎在任何情况下均无效。

即使您将程序简化为:

int main() {
    std::list<int> list0 { 1 , 2 , 3 } ;
    auto iter = std::next(list0.end());
}

它会无效。您可以与.end()迭代器进行比较,但不能取消引用它,也不能通过std::next迭代它。这是未定义的行为。

如果您想要使用列表中的每个项目,只需执行以下操作:

for(auto & reference_to_current : list0) {
    /* ... */
}

或者,如果你坚持使用迭代器,

for(auto current =  list0.begin()
   ;     current != list0.end()
   ;  ++ current)
{ /* ... */ }

是的,这将包括每个项目,包括最后一项。 .end()迭代器是特殊的 - 它不指向最后一个项目,它指向最后一个项目后的下一个槽。 “一过去最末尾”。

最后,next(list0.begin())会跳过第一项。您确定要跳过第一项吗?

更新: 如果你想要跳过第一项,但是使用所有其他项目,你可以使用

if(list0.empty()) {
    /* Error, list must not be empty */
} else {
    for(auto current =  std::next(list0.begin()) // skip first item
       ;     current !=           list0.end()
   ;  ++ current)
    { /* ... */ }
}

if非常重要,因为如果列表为空,我们不得调用std::next(list0.begin())