#include <iostream>
template <typename Derive>
struct swim {
swim(const Derive &d) : self(d) {
}
void to_swim() {
std::cout << self.name << " can swim." << std::endl;
}
const Derive &self;
};
template <typename Derive>
struct fly {
fly(const Derive &d) : self(d) {
}
void to_fly() {
std::cout << self.name << " can fly." << std::endl;
}
const Derive &self;
};
template <typename Derive>
struct jump {
jump(const Derive &d) : self(d) {
}
void to_jump() {
std::cout << self.name << " can jump." << std::endl;
}
const Derive &self;
};
template <template<typename ...>class ...Impl>
struct animal : public Impl<animal<Impl...>>... {
animal(const char *p) : name(p), Impl<animal<Impl...>> {*this}... {
}
const char *name;
};
int main() {
animal<fly, jump>m0("m0");
animal<swim, fly, jump>m1("m1");
m0.to_fly();
m0.to_jump();
m1.to_fly();
m1.to_jump();
m1.to_swim();
return 0;
}