std::list iterator: get next element

前端 未结 6 1753
情书的邮戳
情书的邮戳 2021-02-08 21:59

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 stri

相关标签:
6条回答
  • 2021-02-08 22:29

    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.

    0 讨论(0)
  • 2021-02-08 22:35

    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();
    }
    
    0 讨论(0)
  • 2021-02-08 22:35

    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.

    0 讨论(0)
  • 2021-02-08 22:38

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

    0 讨论(0)
  • 2021-02-08 22:41

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

    You can use boost::next and boost::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();
    }
    
    0 讨论(0)
  • 2021-02-08 22:42

    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.h from Google's Usenet archive (or various web sites).

    0 讨论(0)
提交回复
热议问题