#include <iostream>
#include <algorithm>
#include <vector>

class Mensch{
public: 
    void eat(){ std::cout << "Essen\n";}
};

class Maus{
public:
    void eat(){ std::cout << "Nagen\n";}
};

class Huhn{
public: 
    void eat(){ std::cout << "Picken\n";}
};

template <typename T>
void apply_eat(T& t){
    t.eat();
}


template <typename... Others>
class Zoo;

template <typename Animal, typename... Others>
class Zoo<Animal, Others...> : public Zoo<Others...>
{
private:
    std::vector<Animal> animals;
public:
    using Zoo<Others...>::add;
    void add(const Animal& f) {
        animals.push_back(f);
    }

    void eat_all(){
        std::for_each(animals.begin(), animals.end(), apply_eat<Animal>);
        animals.clear();
        Zoo<Others...>::eat_all();
	}
};

template <>
class Zoo<>
{
public:
    void add(){}
    void eat_all(){}
};


int main()
{
    Zoo<Huhn, Maus, Mensch> zoo;
    zoo.add(Mensch());
    zoo.add(Huhn());
    zoo.add(Maus()); 
    zoo.add(Huhn()); 
    zoo.eat_all();
    std::cout << "--------------------\n";
    zoo.add(Maus()); 
    zoo.add(Huhn());zoo.add(Huhn()); zoo.add(Huhn());  
    zoo.eat_all();
    return 0;
}
