在 C++ 上循环从第二个(或第 n 个)项目开始的迭代器

发布于 2024-10-03 05:36:26 字数 567 浏览 11 评论 0原文

我正在寻找一种可读的、优雅的方法来在 C++ 中执行以下操作,此处以 Python 所示:

for datum in data[1:]:
    # do work.

The iterators on the data in question might not support random access iterators, so I can't just use:

for (mIter = data.begin() + 1; mIter != data.end(); mIter++)

The best I've come up其内容如下:

iterable::iterator mIter = data.begin();
for (mIter++;  mIter != allMjds.end(); mjdIter++) {
    // do work.
}

它不太长,但很难解释 - 乍一看,它实际上看起来像是一个错误!

我猜另一个解决方案是有一个“第 n 个元素”辅助函数。有没有更简洁的方法?

I am looking for a readable, elegant way to do the following in C++, here shown in Python:

for datum in data[1:]:
    # do work.

The iterators on the data in question may not support random access iterators, so I can't just use:

for (mIter = data.begin() + 1; mIter != data.end(); mIter++)

The best I've come up with is the following:

iterable::iterator mIter = data.begin();
for (mIter++;  mIter != allMjds.end(); mjdIter++) {
    // do work.
}

It's not too lengthy, but it's hardly expository - at first glance it actually looks like a mistake!

Another solution is to have an "nth element" helper function, I guess. Is there a more concise way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

在你怀里撒娇 2024-10-10 05:36:26

您可以使用 std::next(iter, n) 线性时间提前。您还可以使用标准 std::advance算法,尽管它使用起来并不简单(它通过非常量引用获取迭代器并且不返回它)。

例如,

for (mIter = std::next(data.begin()); mIter != data.end(); ++mIter)

或者,

mIter = data.begin();
std::advance(mIter, 1);
for (; mIter != data.end(); ++mIter)

请注意,您必须确保 data.size() >= 1,否则代码将以灾难性的方式失败。

You can use std::next(iter, n) for a linear-time advance. You can also use the standard std::advance algorithm, though it isn't as simple to use (it takes the iterator by a non-const reference and doesn't return it).

For example,

for (mIter = std::next(data.begin()); mIter != data.end(); ++mIter)

or,

mIter = data.begin();
std::advance(mIter, 1);
for (; mIter != data.end(); ++mIter)

Note that you must make sure that data.size() >= 1, otherwise the code will fail in a catastrophic manner.

陈独秀 2024-10-10 05:36:26
#include <iterator>

iterator iter = data.begin();
for (advance(iter, 1); iter != data.end(); ++iter)
{
  // do work
}

不过,这依赖于 data 中的 >= 1 元素来避免异常。

#include <iterator>

iterator iter = data.begin();
for (advance(iter, 1); iter != data.end(); ++iter)
{
  // do work
}

This relies on >= 1 element in data to avoid an exception, though.

浮生未歇 2024-10-10 05:36:26

您可以尝试:

for (mIter = data.begin() ; ++mIter != data.end() ; )

但您需要确保 if data.begin () == data.end () 执行 ++mIter 不会导致问题。

由于这是一个非标准的 for 循环,因此使用 while 循环可能更合适,因为关于它们如何工作的先入为主的想法较少,即查看代码的人更有可能阅读 while 语句而不是 for 语句,因为通常是他们头脑中 for 循环如何工作的模型。

mIter = data.begin ();

while (++mIter != data.end ())
{
}

You could try:

for (mIter = data.begin() ; ++mIter != data.end() ; )

but you'd need to make sure that if data.begin () == data.end () doing the ++mIter doesn't cause a problem.

Since this is a non-standard for loop, using a while loop might be more appropriate as there are fewer preconceived ideas about how they work, i.e. people looking at your code are more likely to read a while statement than a for statement as there is usually a model of how a for loop should work in their head.

mIter = data.begin ();

while (++mIter != data.end ())
{
}
忆梦 2024-10-10 05:36:26

您可以为此使用 boost::next (但在执行此操作之前您应该确保列表中实际上有一个元素):

#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>

#include <boost/assign.hpp>
#include <boost/next_prior.hpp>
using namespace boost::assign;

int main()
{
    std::list<int> lst = list_of(23)(9)(84)(24)(12)(18);
    std::copy(boost::next(lst.begin()), lst.end(), std::ostream_iterator<int>(std::cout, " "));
    return 0;
}

You can use boost::next for this (but you should be sure that the list actually has an element in it before doing so):

#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>

#include <boost/assign.hpp>
#include <boost/next_prior.hpp>
using namespace boost::assign;

int main()
{
    std::list<int> lst = list_of(23)(9)(84)(24)(12)(18);
    std::copy(boost::next(lst.begin()), lst.end(), std::ostream_iterator<int>(std::cout, " "));
    return 0;
}
Smile简单爱 2024-10-10 05:36:26
iterable::iterator mIter = data.begin();    
std::for_each(++mIter, data.end(), some_func);

其中 some_func 包含您想要执行的代码...您甚至可以使用简单的包装函数来简化它

template <typename _cont, typename _func>
for_1_to_end(_cont const& container, some_func func)
{
  typename _cont::const_iterator it = _cont.begin();
  std::for_each(++it, _cont.end(), func);
}
iterable::iterator mIter = data.begin();    
std::for_each(++mIter, data.end(), some_func);

where some_func contains the code you want to execute... you could even trivialise it with a simple wrapper function

template <typename _cont, typename _func>
for_1_to_end(_cont const& container, some_func func)
{
  typename _cont::const_iterator it = _cont.begin();
  std::for_each(++it, _cont.end(), func);
}
北方。的韩爷 2024-10-10 05:36:26

我就是这样做的

// starting position in the list
int i = 4;

// initialize "it" to point to the first item of data.
std::list<int>::iterator it = data_list.begin();

if (i < data.size()) {
    // loop starting from 4 to end of the list.
    for (std::advance(it, i); it != token_list.end(); it++) {
        //use "it" here
    }
}
else {
    // Error: starting point is greater than size of data
}

This is how i would do it

// starting position in the list
int i = 4;

// initialize "it" to point to the first item of data.
std::list<int>::iterator it = data_list.begin();

if (i < data.size()) {
    // loop starting from 4 to end of the list.
    for (std::advance(it, i); it != token_list.end(); it++) {
        //use "it" here
    }
}
else {
    // Error: starting point is greater than size of data
}
尽揽少女心 2024-10-10 05:36:26

以现代 C++ 方式可能是一个好的解决方案:

std::for_each(cbegin(data)+1,cend(data),[&](const auto& elem)
{
    //do whatever you want with elem here
});

即使 data 为空,这也会起作用。基本上可以按照与使用标准 for-range 循环完全相同的方式使用它,并且具有不需要任何附加变量同时保持代码可读的优点。

算法库:https://en.cppreference.com/w/cpp/algorithm

What might be a good solution in a modern c++ way :

std::for_each(cbegin(data)+1,cend(data),[&](const auto& elem)
{
    //do whatever you want with elem here
});

This will work even if data is empty. It's basically possible to use this in the exact same way as you would do it with a standard for-range loop and has the advantage not to require any additional variable while keeping the code readable.

Algorithm library : https://en.cppreference.com/w/cpp/algorithm

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文