Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort a std::vector by type

I was watching http://channel9.msdn.com/Events/GoingNative/2013/Writing-Quick-Code-in-Cpp-Quickly and around min 36, they talk about the benefits of sorting a collection by the type of its elements if you are going to be calling virtual methods on them.

So given

class Base {};
class Der1 : public Base {};
class Der2 : public Base {};
class Der3 : public Base {};

vector<Base *> myVector;

How could you sort myVector in such a way that the elements of each type are all adjecent?

Is there any way to do that without using a virtual function in order to indentify each derived type? (Maybe using typeid?)

like image 858
José D. Avatar asked Apr 15 '14 13:04

José D.


People also ask

How do you sort a std vector?

Sorting a vector in C++ can be done by using std::sort(). It is defined in<algorithm> header. To get a stable sort std::stable_sort is used. It is exactly like sort() but maintains the relative order of equal elements.

How do you sort a class vector in C++?

You can sort a vector of custom objects using the C++ STL function std::sort. The sort function has an overloaded form that takes as arguments first, last, comparator. The first and last are iterators to first and last elements of the container.

How do you sort a vector without using the sort function?

The vector can use the array notation to access the elements. If you don't want to use the default std::sort , or std::sort with custom comparator, you can use qsort or write your own.

Can we sort const vector?

Yes, you can sort a const vector in C++.


1 Answers

You can use type_index for this. You constructing one from a type_info object that's returned from typeid operator. It's a class with overloaded relational operators with well defined ordering, so that it is useful as a key type in associative containers and alike.

Here's an example:

#include <typeinfo>
#include <typeindex>
#include <vector>
#include <algorithm>
#include <iostream>

struct Base {
    virtual ~Base() {}
    virtual const char* who() = 0;
};
struct D1 : Base { const char* who() { return "D1\n"; } };
struct D2 : Base { const char* who() { return "D2\n"; } };
struct D3 : Base { const char* who() { return "D3\n"; } };

int main()
{
    std::vector<Base*> vec { new D2, new D1, new D3, new D3, new D1, new D2 };
    std::sort( vec.begin(), vec.end(),
    [](const Base* p1, const Base* p2)
    {
        return
            std::type_index(typeid(*p1)) <
            std::type_index(typeid(*p2));
    });

    for (auto p : vec) { std::cout << p->who(); }
}

The output is:

D1
D1
D2
D2
D3
D3
like image 129
jrok Avatar answered Sep 29 '22 20:09

jrok