【问题标题】:Preventing an iterator from traversing past the end of a container防止迭代器遍历容器的末端
【发布时间】:2019-07-18 08:19:03
【问题描述】:

我正在开发自己的 for_each 类型函数,通过某个整数 N

这是我的函数目前的样子:

template<typename Container, typename Function>
void for_each_by_n( Container&& cont, Function f, unsigned increment_by ) {
    using std::begin;
    auto it = begin(cont);

    using std::end;
    auto end_it = end(cont);

    while ( it != end_it ) { // traverse the full container
        f(*it);  // call the function pointer - object etc.
        for ( unsigned n = 0; n < increment_by; ++n ) {
            // here I want to increment the pointer as long as the next iteration of
            // increment_by is within the bounds of the range of the container
            if ( .... tried many things .... ) return; // and or break;
            ++it;
        }
    }
}

我最后一次尝试内部 if 语句是这样的:

if ( n % increment_by > (cont.size() - n) ) return; // and or break;

但是,我不断收到调试断言失败,我无法遍历容器索引的末尾。这让我很困惑,我不知道如何防止迭代结束。

【问题讨论】:

    标签: debugging iterator containers c++17 assertion


    【解决方案1】:

    好的,我离开电脑大约 30 秒到一分钟,然后它就来了。我完全想多了,这实际上是一个简单的修复。

    我对 if 语句所要做的就是:

    if ( it == end_it ) return;
    

    现在它可以正常工作了。无需根据索引指针与末尾的比较位置进行计算。我所要做的就是比较它们是否相等,如果相等就返回。

    所以完整的函数现在看起来像这样:

    // positive direction from begin to end only
    template<typename Container, typename Function>
    void for_each_by_n(Container&& cont, Function f, unsigned increment_by) {
        using std::begin;
        auto it = begin(cont);
    
        using std::end;
        auto end_it = end(cont);
    
        while (it != end_it ) {
            f(*it);
            for ( unsigned n = 0; n < increment_by; ++n ) {
                if (it == end_it) {
                    return;
                }
                ++it;
            }
        }
    }
    

    一定是那个coders_block综合症……

    【讨论】:

      【解决方案2】:

      这里的关键是要意识到你想要cont的每个块的第一个元素,每个块都是increment_by元素。因此有cont.size()/increment_by 块。无需检查是否到达最后一个迭代器,只需计算块。

      不需要++it。使用std::advance(increment_by),随机访问迭代器要快得多。

      【讨论】:

      • 你提到了std::advanced,这很有趣,因为我实际上是从cppreference 看到的,但是,它对我来说是新的,所以我有点努力尝试合并它。我在上面调用这个函数并传入一个 lambda 作为函数参数。
      猜你喜欢
      • 1970-01-01
      • 2016-09-03
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      • 2010-10-28
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      相关资源
      最近更新 更多