#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <memory>
struct Animal
{ virtual void say() const {std::cout << "...\n";} };
struct Dog : Animal
{ virtual void say() const override {std::cout << "Woof\n";} };
struct Cat : Animal
{ virtual void say() const override {std::cout << "Meow\n";} };
struct Cow : Animal
{ virtual void say() const override {std::cout << "Moo\n";} };
using Animals = std::vector<std::unique_ptr<Animal>>;
Animals populate(std::istream& in)
{
Animals result;
std::string animal;
while(in >> animal)
if (animal == "cow")
result.emplace_back(new Cow);
else if (animal == "cat")
result.emplace_back(new Cat);
else if (animal == "dog")
result.emplace_back(new Dog);
else
result.emplace_back(new Animal);
return result;
}
int main()
{
std::istringstream input("cat cat cow dog cow foo");
auto animals = populate(input);
for(const auto& v: animals)
v -> say();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8c3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPG1lbW9yeT4KCnN0cnVjdCBBbmltYWwKeyB2aXJ0dWFsIHZvaWQgc2F5KCkgY29uc3Qge3N0ZDo6Y291dCA8PCAiLi4uXG4iO30gfTsKCnN0cnVjdCBEb2cgOiBBbmltYWwKeyB2aXJ0dWFsIHZvaWQgc2F5KCkgY29uc3Qgb3ZlcnJpZGUge3N0ZDo6Y291dCA8PCAiV29vZlxuIjt9IH07CgpzdHJ1Y3QgQ2F0IDogQW5pbWFsCnsgdmlydHVhbCB2b2lkIHNheSgpIGNvbnN0IG92ZXJyaWRlIHtzdGQ6OmNvdXQgPDwgIk1lb3dcbiI7fSB9OwoKc3RydWN0IENvdyA6IEFuaW1hbAp7IHZpcnR1YWwgdm9pZCBzYXkoKSBjb25zdCBvdmVycmlkZSB7c3RkOjpjb3V0IDw8ICJNb29cbiI7fSB9OwoKdXNpbmcgQW5pbWFscyA9IHN0ZDo6dmVjdG9yPHN0ZDo6dW5pcXVlX3B0cjxBbmltYWw+PjsKCkFuaW1hbHMgcG9wdWxhdGUoc3RkOjppc3RyZWFtJiBpbikKewogICAgQW5pbWFscyByZXN1bHQ7CiAgICBzdGQ6OnN0cmluZyBhbmltYWw7CiAgICB3aGlsZShpbiA+PiBhbmltYWwpCiAgICAgICAgaWYgKGFuaW1hbCA9PSAiY293IikKICAgICAgICAgICAgcmVzdWx0LmVtcGxhY2VfYmFjayhuZXcgQ293KTsKICAgICAgICBlbHNlIGlmIChhbmltYWwgPT0gImNhdCIpCiAgICAgICAgICAgIHJlc3VsdC5lbXBsYWNlX2JhY2sobmV3IENhdCk7CiAgICAgICAgZWxzZSBpZiAoYW5pbWFsID09ICJkb2ciKQogICAgICAgICAgICByZXN1bHQuZW1wbGFjZV9iYWNrKG5ldyBEb2cpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmVzdWx0LmVtcGxhY2VfYmFjayhuZXcgQW5pbWFsKTsKICAgIHJldHVybiByZXN1bHQ7Cn0KCmludCBtYWluKCkKewogICAgc3RkOjppc3RyaW5nc3RyZWFtIGlucHV0KCJjYXQgY2F0IGNvdyBkb2cgY293IGZvbyIpOwogICAgYXV0byBhbmltYWxzID0gcG9wdWxhdGUoaW5wdXQpOwogICAgZm9yKGNvbnN0IGF1dG8mIHY6IGFuaW1hbHMpCiAgICAgICAgdiAtPiBzYXkoKTsKfQo=