0

For example:

If I wanted to create a message manager which among other functions would maintain a time-ordered list of messages, structured something like this.

class Message { MessageHeader header; MessageData data; }; 

where the header structure would, among other elements, contain a creation time-stamp.

struct MessageHeader { uint64_t timeStamp; userId_t sender; userId_t receiver; /* ... */ }; 

Is it possible using an existing container in the STL library to order the messages by the time stamp? I would be using nanosecond time stamps, so the likelihood of not unique values would be low.

0

2 Answers 2

3

Yes.

Ordered containers typically use operator< by default and let you specify a custom comparator. For example for a std::map<Message> all you need to add is:

struct Message { MessageHeader header; MessageData data; bool operator<(const Message& other) const { return header.timeStamp < other.header.timeStamp; } }; 

to have the map sorted according to the timestamps.

However, note that this comparison is used to establish a notion of equivalence according to:

!comp(a,b) && !comp(b,a) => a is equivalent to b 

Which means: If two different messages have the same timestamp then neither of them compares smaller than the other hence they are considered as equivalent by the map. You should make sure that this cannot happen, by making sure that different messages are guaranteed to have different timestamps.

Sign up to request clarification or add additional context in comments.

3 Comments

Make sure you're confident that timestamps are actually unique. If the ordering implied by your specified operator< isn't actually a strict weak ordering, you can run into trouble.
Also I would suggest making operator< itself a const member method.
@NathanPierson thanks will add a note, and const is fixed
2

If objects of your type have a natural ordering, then implement that in operator< for the type. If you just want to define a type that is a container with objects sorted in some specific fashion, then you can pass a predicate directly to STL containers such as std::set and std::map.

From c++20, you can create such a type quite conveniently:

using UniqueTimedMessages = std::set<Message, decltype([](auto const& a, auto const &b){ return a.header.timeStamp < b.header.timeStamp; })>; 

3 Comments

as OP is asking for having the container order specifically not according to the types natural order but according to one of its members, this answer is much better than mine. One of the cases where I wouldn't know how to fix my answer other than stealing from here, so I just leave it as is
@idclev463035818 Thanks :) In fact, OP is asking about this and I was about to hammer it, but saw that the solution there didn't make it as convenient as it could be, so figured I'd add something :)
@idclev463035818 Oh, and feel free to "steal" from my answers :) You can always say where you got it from.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.