Skip to content

Instantly share code, notes, and snippets.

@Rhomboid
Created May 8, 2013 04:08
Show Gist options
  • Select an option

  • Save Rhomboid/5538125 to your computer and use it in GitHub Desktop.

Select an option

Save Rhomboid/5538125 to your computer and use it in GitHub Desktop.
Heterogeneous polymorphic vector sorting example in C++11
#include <string>
#include <iostream>
#include <tuple>
#include <memory>
#include <algorithm>
using namespace std;
typedef tuple<string, int, string> sort_key_t;
class AnimalBase {
virtual ostream & out(ostream &) = 0;
public:
virtual sort_key_t get_key() = 0;
friend ostream & operator<<(ostream & os, AnimalBase &a) { return a.out(os); }
};
class Cow : public AnimalBase {
string name_;
int age_;
virtual sort_key_t get_key() override { return sort_key_t("cow", age_, name_); }
virtual ostream & out(ostream & os) override {
return os << "A cow age " << age_ << " named " << name_ << endl;
}
public:
Cow(string name, int age) : name_(name), age_(age) {}
};
class Dog : public AnimalBase {
string name_;
int age_;
virtual sort_key_t get_key() override { return sort_key_t("dog", age_, name_); }
virtual ostream & out(ostream & os) override {
return os << "A dog age " << age_ << " named " << name_ << endl;
}
public:
Dog(string name, int age) : name_(name), age_(age) {}
};
class Kitty : public AnimalBase {
string name_;
int age_;
virtual sort_key_t get_key() override { return sort_key_t("kitty", age_, name_); }
virtual ostream & out(ostream & os) override {
return os << "A kitty age " << age_ << " named " << name_ << endl;
}
public:
Kitty(string name, int age) : name_(name), age_(age) {}
};
int main()
{
vector<unique_ptr<AnimalBase>> barnyard;
barnyard.emplace_back(new Kitty("Puss-n-boots", 2));
barnyard.emplace_back(new Kitty("Mr. Pickles", 2));
barnyard.emplace_back(new Dog("Fifo", 3));
barnyard.emplace_back(new Cow("Bluebell", 6));
barnyard.emplace_back(new Dog("Muttsworth", 2));
barnyard.emplace_back(new Cow("Bessy", 6));
cout << "Before sort:\n";
for(auto & a : barnyard)
cout << *a;
sort(begin(barnyard), end(barnyard), [](const unique_ptr<AnimalBase> & a, const unique_ptr<AnimalBase> & b) {
return a->get_key() < b->get_key(); });
cout << "\n\nAfter sorting by species then age then name:\n";
for(auto & a : barnyard)
cout << *a;
}
$ g++ -Wall -Wextra -pedantic -std=c++11 -O2 20130507.cpp -o 20130507 && ./20130507
Before sort:
A kitty age 2 named Puss-n-boots
A kitty age 2 named Mr. Pickles
A dog age 3 named Fifo
A cow age 6 named Bluebell
A dog age 2 named Muttsworth
A cow age 6 named Bessy
After sorting by species then age then name:
A cow age 6 named Bessy
A cow age 6 named Bluebell
A dog age 2 named Muttsworth
A dog age 3 named Fifo
A kitty age 2 named Mr. Pickles
A kitty age 2 named Puss-n-boots
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment