0

With only one field is easy:

bool operator<(const MidiMsg &midiMsg) const {
    return (mPosition < midiMsg.mPosition);
}

But what if I need to order first by 1 member, than by another?

Tried this:

bool operator<(const MidiMsg &midiMsg) const {
    return (mPosition < midiMsg.mPosition && mId < midiMsg.mId);
}

But it seems that doesn't works.

Here's a working example:

#include <iostream>
#include <deque>
#include <algorithm>

struct MidiMsg {
    int mPosition;
    int mId;

    bool operator<(const MidiMsg &midiMsg) const {
        return (mPosition < midiMsg.mPosition && mId < midiMsg.mId);
    }
};

int main() {
    std::cout.precision(10);

    std::deque<MidiMsg> mNotes;

    MidiMsg note;

    note.mPosition = 0;
    note.mId = 1;
    mNotes.push_back(note);

    note.mPosition = 44100;
    note.mId = 1;
    mNotes.push_back(note);

    note.mPosition = 0;
    note.mId = 0;
    mNotes.push_back(note);

    note.mPosition = 44100;
    note.mId = 0;
    mNotes.push_back(note);

    note.mPosition = 0;
    note.mId = 2;
    mNotes.push_back(note);

    note.mPosition = 44100;
    note.mId = 2;
    mNotes.push_back(note);    

    std::sort(mNotes.begin(), mNotes.end());

    for (size_t index = 0; index < mNotes.size(); index++) {
        std::cout << mNotes[index].mPosition << " - " << mNotes[index].mId << std::endl;
    }
}

Which outputs:

0 - 1
0 - 0
44100 - 1
44100 - 0
0 - 2
44100 - 2

and not:

0 - 0
0 - 1   
0 - 2   
44100 - 0   
44100 - 1
44100 - 2
markzzz
  • 47,390
  • 120
  • 299
  • 507
  • 1
    You'd need some extra checks: `(mPosition < midiMsg.mPosition || ( mPosition == midiMsg.mPosition && mId < midiMsg.mId));`. – xEric_xD Sep 17 '19 at 14:26
  • @xEric_xD it seems correct. And if you have third? A chain of ||? – markzzz Sep 17 '19 at 14:28
  • @markzzz That would work, but it'll quickly get messy, there's probably better solutions for a large number of properties. – xEric_xD Sep 17 '19 at 14:31
  • @markzzz `std::tie` mentioned earlier does this but cleanly. Otherwise, you an apply Eric's solution more cleanly by chaining `if/else if`s instead of chaining `||`s. – François Andrieux Sep 17 '19 at 14:33
  • Here's the result, not so fancy to use hehe `(mPosition < midiMsg.mPosition || ( mPosition == midiMsg.mPosition && mNoteNumber < midiMsg.mNoteNumber) || ( mPosition == midiMsg.mPosition && mNoteNumber == midiMsg.mNoteNumber && mId < midiMsg.mId));` :) Any other solution? – markzzz Sep 17 '19 at 14:34
  • 1
    @markzzz `return std::tie(mPosition, mNoteNumber, mId) < std::tie(midiMsg.mPosition, midiMsg.mNoteNumber, midiMsg.mId);` – aschepler Sep 17 '19 at 14:37
  • @aschepler it seems to works perfectly! Thanks! p.s. if you reply, you will get the accepted answer! – markzzz Sep 17 '19 at 14:39
  • See the accepted answer at the duplicate for why it works. – aschepler Sep 17 '19 at 14:40

0 Answers0