gpt4 book ai didi

c++ - 基于范围的 for 和其他增量

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:12:42 27 4
gpt4 key购买 nike

假设我们需要迭代一个容器。传统的 for 循环看起来像这样:

for (auto it = container.begin(), end = container.end();
it != end;
++it)
{
doStuff(*it);
}

虽然基于范围的 for 看起来像这样:

for (auto& element : container)
{
doStuff(element);
}

现在,在开发的某个阶段,我们意识到出于某种原因,我们需要在这些循环迭代中增加一些其他东西。

需要增加的可能是各种各样的东西。例如,如果我们将相关数据存储在其他相同大小的容器中,我们可能也需要在迭代过程中将迭代器递增到这些容器(尽管我希望标准库的 future 版本将允许我们做更多的事情)表达方式,通过结构化绑定(bind)和标准版本的 boost::range::combine 或其他东西)。

在下文中,为了简单起见,我们假设我们要为每个元素分配一个 ID,因此需要递增的只是一个计数器。


传统的循环现在看起来像这样:

unsigned int elementID = 0u;
for (auto it = container.begin(), end = container.end();
it != end;
++it, ++elementID)
{
doStuff(*it, elementID);
}

几乎不需要更改任何内容,在 ++it 之后添加 ++elementID 可确保无论每次迭代后发生什么,计数器都会递增。即使另一个程序员要修改循环体,比如说,在某些条件下通过 continue 提前进入下一次迭代,他们也不会有忘记递增计数器或类似的东西的风险那个。


现在,据我所知,使用基于范围的 for 进行递增的唯一方法是执行如下操作:

unsigned int elementID = 0u;
for (auto& element : container)
{
doStuff(element, elementID);
++elementID;
}

也就是说,将增量放在循环体内。

这对于 elementID 的表现力较低(即,如果代码主体很长,阅读代码的人不会一眼就看出我们正在遍历 elementID 也是),它不能提供我上面提到的保证,所以它也容易出错。

真的没有其他方法可以用基于范围的 for 来实现吗?或者有没有一种方法可以按照 for(auto& element : container;++elementID){...} 的方式编写我根本不知道的内容?


在人们回答后编辑

Nevin 建议使用 boost 的 BOOST_SCOPE_EXIT_ALL,就非本地解决方案而言,它最接近我的想法。

我不确定实际的实现,但我猜这依赖于 lambda 和析构函数。我写这个是为了测试它:

template <typename T>
class ScopeExitManager
{
public:
ScopeExitManager(T const& functionToRunOnExit) : _functionToRunOnExit(functionToRunOnExit)
{
}

~ScopeExitManager()
{
_functionToRunOnExit();
}

private:
T _functionToRunOnExit;
};


template <typename T>
ScopeExitManager<T> runOnScopeExit(T const& functionToRunOnExit)
{
return {functionToRunOnExit};
}

这让我可以按照以下方式写一些东西:

unsigned int elementID = 0u;
for (auto& element : container)
{
// Always at the beginning of the loop
auto scopeExitManager = runOnScopeExit([&elementID](){++elementID;});

// Actual body of the loop
doStuff(element, elementID);
}

它具有表现力并保证 elementID 将递增。这太棒了!

最佳答案

实现此目的的另一种方法是使用类似 Boost.ScopeExit 的东西,如:

unsigned int elementID = 0u;
for (auto& element : container)
{
BOOST_SCOPE_EXIT_ALL(&) { ++elementID; };
doStuff(element, elementID);
}

关于c++ - 基于范围的 for 和其他增量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56604377/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com