#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;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8dmVjdG9yPgoKY2xhc3MgTWVuc2NoewpwdWJsaWM6IAogICAgdm9pZCBlYXQoKXsgc3RkOjpjb3V0IDw8ICJFc3NlblxuIjt9Cn07CgpjbGFzcyBNYXVzewpwdWJsaWM6CiAgICB2b2lkIGVhdCgpeyBzdGQ6OmNvdXQgPDwgIk5hZ2VuXG4iO30KfTsKCmNsYXNzIEh1aG57CnB1YmxpYzogCiAgICB2b2lkIGVhdCgpeyBzdGQ6OmNvdXQgPDwgIlBpY2tlblxuIjt9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kdm9pZCBhcHBseV9lYXQoVCYgdCl7CiAgICB0LmVhdCgpOwp9CgoKdGVtcGxhdGUgPHR5cGVuYW1lLi4uIE90aGVycz4KY2xhc3MgWm9vOwoKdGVtcGxhdGUgPHR5cGVuYW1lIEFuaW1hbCwgdHlwZW5hbWUuLi4gT3RoZXJzPgpjbGFzcyBab288QW5pbWFsLCBPdGhlcnMuLi4+IDogcHVibGljIFpvbzxPdGhlcnMuLi4+CnsKcHJpdmF0ZToKICAgIHN0ZDo6dmVjdG9yPEFuaW1hbD4gYW5pbWFsczsKcHVibGljOgogICAgdXNpbmcgWm9vPE90aGVycy4uLj46OmFkZDsKICAgIHZvaWQgYWRkKGNvbnN0IEFuaW1hbCYgZikgewogICAgICAgIGFuaW1hbHMucHVzaF9iYWNrKGYpOwogICAgfQoKICAgIHZvaWQgZWF0X2FsbCgpewogICAgICAgIHN0ZDo6Zm9yX2VhY2goYW5pbWFscy5iZWdpbigpLCBhbmltYWxzLmVuZCgpLCBhcHBseV9lYXQ8QW5pbWFsPik7CiAgICAgICAgYW5pbWFscy5jbGVhcigpOwogICAgICAgIFpvbzxPdGhlcnMuLi4+OjplYXRfYWxsKCk7Cgl9Cn07Cgp0ZW1wbGF0ZSA8PgpjbGFzcyBab288Pgp7CnB1YmxpYzoKICAgIHZvaWQgYWRkKCl7fQogICAgdm9pZCBlYXRfYWxsKCl7fQp9OwoKCmludCBtYWluKCkKewogICAgWm9vPEh1aG4sIE1hdXMsIE1lbnNjaD4gem9vOwogICAgem9vLmFkZChNZW5zY2goKSk7CiAgICB6b28uYWRkKEh1aG4oKSk7CiAgICB6b28uYWRkKE1hdXMoKSk7IAogICAgem9vLmFkZChIdWhuKCkpOyAKICAgIHpvby5lYXRfYWxsKCk7CiAgICBzdGQ6OmNvdXQgPDwgIi0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOwogICAgem9vLmFkZChNYXVzKCkpOyAKICAgIHpvby5hZGQoSHVobigpKTt6b28uYWRkKEh1aG4oKSk7IHpvby5hZGQoSHVobigpKTsgIAogICAgem9vLmVhdF9hbGwoKTsKICAgIHJldHVybiAwOwp9Cg==