#include <iostream>

namespace so {
template<typename _t_derived_>
class _animal_ {
private:
	using _derived_ = _t_derived_;
public:
	void eat() const {
		static_cast<_derived_ const *>(this)->eat_impl();
	}
};

class _dog_: public _animal_<_dog_> {
	friend class _animal_<_dog_> ;
private:
	using _base_ = _animal_<_dog_>;
protected:
	void eat_impl() const {
		std::cout << "dog's eating." << std::endl;
	}
};

class _cat_: public _animal_<_cat_> {
	friend class _animal_<_cat_> ;
private:
	using _base_ = _animal_<_cat_>;
protected:
	void eat_impl() const {
		std::cout << "cat's eating." << std::endl;
	}
};

template<typename _t_animal_>
void feed(_t_animal_ const & _animal) {
	std::cout << "feeding an animal: ";
	_animal.eat();
}
} // namespace so

int main() {
	so::_dog_ dog_;
	so::_cat_ cat_;

	so::feed(dog_);
	so::feed(cat_);

	return (0);
}