Is there a sorted container in the STL?
What I mean is following: I have an std::vector<Foo>
, where Foo
is a custom made class. I also have a comparator of some sort which will compare the fields of the class Foo
.
Now, somewhere in my code I am doing:
std::sort( myvec.begin(), myvec.end(), comparator );
which will sort the vector according to the rules I defined in the comparator.
Now I want to insert an element of class Foo
into that vector. If I could, I would like to just write:
mysortedvector.push_back( Foo() );
and what would happen is that the vector will put this new element according to the comparator to its place.
Instead, right now I have to write:
myvec.push_back( Foo() );
std::sort( myvec.begin(), myvec.end(), comparator );
which is just a waste of time, since the vector is already sorted and all I need is to place the new element appropriately.
Now, because of the nature of my program, I can't use std::map<>
as I don't have a key/value pairs, just a simple vector.
If I use stl::list
, I again need to call sort after every insertion.
C++ do have sorted container e.g std::set and std::map
Output: Elements of set in sorted order: 1 2 3 5 6 7
Output:
1 : 1
3 : 5
5 : 10
20 : 100
Yes,
std::set
,std::multiset
,std::map
, andstd::multimap
are all sorted usingstd::less
as the default comparison operation. The underlying data-structure used is typically a balanced binary search tree such as a red-black tree. So if you add an element to these data-structures and then iterate over the contained elements, the output will be in sorted order. The complexity of adding N elements to the data-structure will be O(N log N), or the same as sorting a vector of N elements using any common O(log N) complexity sort.In your specific scenario, since you don't have key/value pairs,
std::set
orstd::multiset
is probably your best bet.I'd like to expand on Jason's answer. I agree to Jason, that either
std::set
orstd::multiset
is the best choice for your specific scenario. I'd like to provide an example in order to help you to further narrow down the choice.Let's assume that you have the following class
Foo
:Here,
Foo
overloads the<
operator. This way, you don't need to specify an explicit comparator function. As a result, you can simply use astd::multiset
instead of astd::vector
in the following way. You just have to replacepush_back()
byinsert()
:Output:
As you can see, the container is sorted by the member
val2
of the classFoo
, based on the<
operator. However, if you usestd::set
instead of astd::multiset
, then you will get a different output:Output:
Here, the second
Foo
object whereval2
is 4 is missing, because astd::set
only allows for unique entries. Whether entries are unique is decided based on the provided<
operator. In this example, the<
operator compares theval2
members to each other. Therefore, twoFoo
objects are equal, if theirval2
members have the same value.So, your choice depends on whether or not you want to store
Foo
objects that may be equal based on the<
operator.Code on Ideone