在range-for循环中能否查看下一个元素?

5

假设我有以下代码:

void test(std::vector<int>& my_ints) {
    for (auto& my_int : my_ints) {
        if (my_int == 5 && /* not the last value in the vector */) {
            my_int += /* next value in the vector */;
        }
    }
}

是否有任何有效的语法来替换注释?

PS!是的,我知道,使用常规for循环很容易,但是我想看看是否可以使用范围for循环来处理这种类型的内容。


你可以为向量创建一个薄包装器,其中包含一个迭代器,该迭代器返回一对引用而不是仅返回一个。 - Marc Glisse
3个回答

6

能否窥视下一个元素?

一般情况下-不行。

由于在 std::vector 中,对象是连续存储的,你可以使用*(&my_int + 1),但如果稍后更改容器,则代码可能会悄无声息地中断。不要那样做!


检查当前元素是否为最后一个元素,可以使用&my_int == &my_ints.back()


0

我无法想到使用范围循环实现您要求的安全方法。

如果您可以承受额外的辅助函数,您可以以某种方式概括您正在使用的算法:

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

template <class Container, class BinaryOp>
void apply_using_the_next(Container& cc, BinaryOp op)
{
    if (std::cbegin(cc) == std::cend(cc))
        return;
    std::transform(std::begin(cc), std::prev(std::end(cc)),
                   std::next(std::cbegin(cc)),
                   std::begin(cc), op);
}

void test(std::vector<int>& v)
{
    apply_using_the_next(v, [] (const int a, const int b) {
        return a == 5 ? a + b : a;
    });
}

int main()
{
    std::vector<int> a{2, 5, 4, 3, 5, 5, 1};

    test(a);

    for (auto const i : a)       // ->  2 9 4 3 10 6 1
        std::cout << ' ' << i;
    std::cout << '\n';
}

现在就开始,点击这里


-4

你可以使用迭代器。

for (std::vector<int>::iterator it = my_ints.begin(); it < my_ints.end() - 1; ++it) {
    if (*it == 5 /* no need to check as iterating until second last value && it != my_ints.end() - 1*/) {
        *it += *(it+1);
    }
}

即使向量为空,循环也不会进入,因为它 < my_ints.end() - 1 将返回 false,因此是安全的。

1
不安全:如果向量为空,则“end() - 1”是未定义的。此外,问题是“如何使用基于范围的循环”来完成此任务,而不是将基于范围的循环转换为迭代器循环。 - Yksisarvinen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接