C++ std::list 迭代器:获取下一个元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2699680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:23:48  来源:igfitidea点击:

std::list iterator: get next element

c++liststliterator

提问by J. Polfer

I'm trying to build a string using data elements stored in a std::list, where I want commas placed only between the elements (ie, if elements are {A,B,C,D} in list, result string should be "A,B,C,D".

我正在尝试使用存储在 std::list 中的数据元素构建一个字符串,我只想在元素之间放置逗号(即,如果元素是列表中的 {A,B,C,D},结果字符串应该是“A B C D”。

This code does not work:

此代码不起作用:

typedef std::list< shared_ptr<EventDataItem> > DataItemList;
// ...
std::string Compose(DataItemList& dilList)
{
    std::stringstream ssDataSegment;
    for(iterItems = dilList.begin();
        iterItems != dilList.end(); 
        iterItems++)
    {
        // Lookahead in list to see if next element is end
        if((iterItems + 1) == dilList.end())  
        {
            ssDataSegment << (*iterItems)->ToString();
        }
        else
        {
            ssDataSegment << (*iterItems)->ToString() << ",";
        }
    }
    return ssDataSegment.str();
}

How do I get at "the-next-item" in a std::list using an iterator? I would expect that it's a linked-list, why can't I get at the next item?

如何使用迭代器获取 std::list 中的“下一项”?我希望它是一个链表,为什么我不能得到下一个项目?

回答by Johannes Schaub - litb

You cannot do it + Nbecause you have no random access for list iterators. You can only do one step at a time with list iterators (these are bidirectional iterators).

您不能这样做,it + N因为您无法随机访问列表迭代器。使用列表迭代器(这些是双向迭代器)一次只能执行一个步骤。

You can use boost::nextand boost::prior

您可以使用boost::nextboost::prior

// Lookahead in list to see if next element is end
if(boost::next(iterItems) == dilList.end())  
{

Or you can print the comma before:

或者您可以在之前打印逗号:

std::string Compose(DataItemList& dilList)
{
    std::stringstream ssDataSegment;
    for(iterItems = dilList.begin();
        iterItems != dilList.end(); 
        ++iterItems)
    {
        if(iterItems != diList.begin())
            ssDataSegment << ",";
        ssDataSegment << (*iterItems)->ToString();
    }
    return ssDataSegment.str();
}

回答by Zan Lynx

I believe that a list iterator is bidirectional, but not random access. That means that you can do ++ and -- to it but not add or subtract.

我相信列表迭代器是双向的,但不是随机访问。这意味着你可以对它做 ++ 和 -- 但不能加或减。

To get the next iterator, make a copy and increment it.

要获得下一个迭代器,请复制并递增它。

回答by Fred Larson

Another solution is to have the first entry be the special case, instead of the last entry:

另一种解决方案是让第一个条目成为特例,而不是最后一个条目:

std::string Compose(DataItemList& dilList)
{
    std::stringstream ssDataSegment;
    for(iterItems = dilList.begin();
        iterItems != dilList.end(); 
        ++iterItems)
    {
        // See if current element is the first
        if(iterItems == dilList.begin())  
        {
            ssDataSegment << (*iterItems)->ToString();
        }
        else
        {
            ssDataSegment << "," << (*iterItems)->ToString();
        }
    }
    return ssDataSegment.str();
}

回答by Danvil

You could avoid this problem altogether by using:

您可以使用以下方法完全避免此问题:

std::string Compose(DataItemList& dilList)
{
    std::stringstream ssDataSegment;
    for(iterItems = dilList.begin(); iterItems != dilList.end(); iterItems++)
    {
        ssDataSegment << (*iterItems)->ToString() << ","; // always write ","
    }
    std::string result = ssDataSegment.str();
    return result.substr(0, result.length()-1); // skip the last ","
}

You first write the "," for all elements (even for the last one). Than afterwards, you remove the unwanted last "," using substr. This additionally results in clearer code.

您首先为所有元素(即使是最后一个)写上“,”。之后,您使用substr. 这另外导致更清晰的代码。

回答by Jerry Coffin

Yet another possibility:

还有一种可能:

#include "infix_iterator.h"
#include <sstream>

typedef std::list<shared_ptr<EventDataItem> > DataItemList;

std::string Compose(DataItemList const &diList) {
    std::ostringstream ret;
    infix_ostream_iterator out(ret, ",");

    for (item = diList.begin(); item != diList.end(); ++item)
        *out++ = (*item)->ToString();
    return ret.str();
}

You can get infix_iterator.hfrom Google's Usenet archive (or various web sites).

您可以从 Google 的 Usenet 存档(或各种网站)获取infix_iterator.h

回答by user1823890

Note: Since C++11 you can use std::nextand std::prev.

注意:从 C++11 开始,您可以使用std::nextstd::prev