【问题标题】:Is it possible to run-time check if an iterator has not gone past the end() iterator?是否可以运行时检查迭代器是否没有超过 end() 迭代器?
【发布时间】:2017-02-23 19:51:05
【问题描述】:

我正在编写一个代码,它使用迭代器上的简单算术将向量分成相等的部分。我的逻辑可能不是很好(尽管我相当确定这是正确的),这可能意味着我在 end() 之后创建了一个无效的迭代器:

//selectWords is a vector<string>
//No is an unsigned integer.

unsigned wordNo = selectWords.size()/No; 
unsigned remainder = selectWords.size()%No; 

for(auto i = 0; i < No; ++i){
    unsigned extra = remainder ? 1 : 0;

    auto b = selectedWords.begin()+(i*wordNo);
    auto e = selectedWords.begin() + ((i+1)*wordNo) + extra;

    if(e > selectedWords.end()) throw logic_error("Iterator e in GridList::createGrids goes past the end of selectWords.") //shouldn't happen unless I've made a mistake.

    ...
    //do stuff
    ...

    if(remainder > 0) --remainder;

}

我很好奇的部分是e &gt; selectedWords.end()。如果e 已经超过end(),那么它是一个无效的迭代器,我不确定是否可以保证比较运算符提供定义的行为。事实上,看看 Ben Voigt 在this thread 和 N3337 的 24.2.7 中的帖子,很明显,使用迭代器算术创建一个 past-the-end() 迭代器是没有意义的或非法的。然而,检查迭代器是否超过 end() 的能力要求对 past-the-end() 迭代器的操作提供定义的行为。

如果做这个比较无效,有没有其他办法?还是我只需要在编译之前绝对确定我的逻辑是正确的?

【问题讨论】:

  • 如果你的迭代器结束了,你给它加一个;实现可以返回 end() - 这意味着您对 iterator > end 的测试将始终为 false。
  • 您可以改为测试((i + 1) * wordNo) + extra &gt; selectedWords.size()

标签: c++ iterator c++14


【解决方案1】:

越过结束迭代器(例如递增它)会产生未定义的行为。

如果某些东西只能作为未定义行为的结果而存在,那么它不能作为在具有明确行为的代码中执行任何操作的结果而存在。从逻辑上讲,这意味着不需要明确的测试方法。

【讨论】:

    【解决方案2】:

    您可以简单地更正您的代码以获得正确的结束位置:

    size_t No = 3;
    std::vector<int> selectWords = {1,2,3,4,5,6,7,8,9,10};
    size_t wordNo = (selectWords.size() + No - 1)/No; 
    size_t remainder = selectWords.size()%No; 
    
    for(size_t i = 0; i < No; ++i){
        size_t start_index = i * wordNo;
        size_t end_index = std::min(selectWords.size(), start_index + wordNo);
        auto b = selectWords.begin() + start_index;
        auto e = selectWords.begin() + end_index;
        for (auto it = b; it != e; ++it)
            std::cout << *it;
     //....
    }
    

    Test it

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-04
      • 2021-09-20
      • 2011-01-18
      • 2023-04-10
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      相关资源
      最近更新 更多