简体   繁体   中英

multimap iterator not working

I have a Playlist class that has a vector with Tracks and each Track has a multimap<long, Note> as datamember.

class Track {
private:
    multimap<long, Note> noteList;
}

Using an iterator to acces the tracks is no problem, so this part here is working fine:

vector<Track>::iterator trackIT;
    try{
        for(noteIT = trackIT->getNoteList().begin(); noteIT != trackIT->getNoteList().end(); noteIT++){
            cout << "---" << noteIT->second.getName() << endl;
        }
    }catch (int e){
        cout << "exception #" << e << endl;
    }

What I want to do next is iterate the Notes of each Track . But starting from this part all output is stopped. So I only get to see the first tracks name. Any cout's after that are not shown and the compiler isn't giving me any errors. Even the cout inside the try catch block isn't working..

vector<Track>::iterator trackIT;
multimap<long, Note>::iterator noteIT;
for(trackIT = this->playlist.getTracklist().begin(); trackIT < this->playlist.getTracklist().end(); trackIT++){
    cout << trackIT->getTrackName() << endl;

    for(noteIT = trackIT->getNoteList().begin(); noteIT != trackIT->getNoteList().end(); noteIT++){
        cout << "---" << noteIT->second.getName() << endl;
    }
}
cout << "random cout that is NOT shown" << endl; // this part doesn't show up in console either

Also, the method in my Track class that I'm using to add the Note objects looks like this:

void Track::addNote(Note &note) {
    long key = 1000009;
    this->noteList.insert(make_pair(key, note));
}

// I'm adding the notes to the track like this:
Note note1(440, 100, 8, 1, 1);
note1.setName("note1");
synthTrack.addNote(note1);

Any ideas why the iterator won't work?

Change

noteIT < trackIT->getNoteList().end()

To

noteIT != trackIT->getNoteList().end()

Not all iterators support less than / greater than comparisons.

If you have c++11 you can use a range-based for loop:

for (Note& note : trackIT->getNoteList())

Or you can use BOOST_FOREACH

BOOST_FOREACH (Note& note, trackIT->getNoteList())

If you are really hardcoding the track key, then there will only ever be one track in the map because std::map stores unique keys...

long key = 1000009; //If yo are really doing this, this key is already inserted so it will fail to insert more.

Also, if you would like a more elegant approach you could use function object.

struct print_track
{
    void operator()(const Track& track)
    {
        cout << track.getTrackName() << endl;
        std::for_each(track.getNoteList().begin(), track.getNoteList().end(), print_track_name());
    }
};

struct print_note_name
{
    void operator()(const std::pair<long,Note>& note_pair)
    {
       cout << "---" << note_pair.second.getName() << endl;
    }
};

//In use...
std::for_each(playlist.getTracklist().begin(), playlist.getTracklist.end(), print_track());

You haven't shown the definitions of getTrackList or getNoteList , but there's a common mistake people make - if you return a copy of the container instead of a reference to it, the iterators will be pointing to different containers making comparisons impossible. Not only that but since the containers are temporary any use of the iterators results in undefined behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM