#include <iostream>
#include <memory>
#include <vector>
class A;
class B;
class C;
class Visitor
{
public:
void visit(A&)
{
std::cout << "A" << std::endl;
}
void visit(B&)
{
std::cout << "B" << std::endl;
}
void visit(C&)
{
std::cout << "C" << std::endl;
}
};
class Base {
public:
virtual void accept(Visitor& v) = 0;
};
class A : public Base{
public:
void accept(Visitor& v) override
{
v.visit(*this);
}
};
class B : public Base{
public:
void accept(Visitor& v) override
{
v.visit(*this);
}
};
class C : public Base{
public:
void accept(Visitor& v) override
{
v.visit(*this);
}
};
class CollectionOfBase
{
public:
void add (std::shared_ptr<Base> item){m_items.push_back(item);}
std::vector<std::shared_ptr<Base>> const& getItems() const {return m_items;}
private:
std::vector<std::shared_ptr<Base>> m_items;
};
int main()
{
using namespace std;
CollectionOfBase collection;
collection.add(make_shared<A>());
collection.add(make_shared<A>());
collection.add(make_shared<C>());
collection.add(make_shared<B>());
Visitor v;
for (auto const& x : collection.getItems())
{
x->accept(v);
}
/*
The desired output of this loop should be:
A
A
C
B
*/
return 0;
}
ICAgICNpbmNsdWRlIDxpb3N0cmVhbT4KCSNpbmNsdWRlIDxtZW1vcnk+CgkjaW5jbHVkZSA8dmVjdG9yPgoJCgljbGFzcyBBOwoJY2xhc3MgQjsKCWNsYXNzIEM7CgljbGFzcyBWaXNpdG9yCgl7CglwdWJsaWM6CgkJdm9pZCB2aXNpdChBJikKCQl7CgkJCXN0ZDo6Y291dCA8PCAiQSIgPDwgc3RkOjplbmRsOwoJCX0KCQl2b2lkIHZpc2l0KEImKQoJCXsKCQkJc3RkOjpjb3V0IDw8ICJCIiA8PCBzdGQ6OmVuZGw7CgkJfQoJCXZvaWQgdmlzaXQoQyYpCgkJewoJCQlzdGQ6OmNvdXQgPDwgIkMiIDw8IHN0ZDo6ZW5kbDsKCQl9Cgl9OwoJCgljbGFzcyBCYXNlIHsKCXB1YmxpYzoKCQl2aXJ0dWFsIHZvaWQgYWNjZXB0KFZpc2l0b3ImIHYpID0gMDsKCX07CgljbGFzcyBBIDogcHVibGljIEJhc2V7CglwdWJsaWM6CgkJdm9pZCBhY2NlcHQoVmlzaXRvciYgdikgb3ZlcnJpZGUKCQl7CgkJCXYudmlzaXQoKnRoaXMpOwoJCX0KCX07CgljbGFzcyBCIDogcHVibGljIEJhc2V7CglwdWJsaWM6CgkJdm9pZCBhY2NlcHQoVmlzaXRvciYgdikgb3ZlcnJpZGUKCQl7CgkJCXYudmlzaXQoKnRoaXMpOwoJCX0KCX07CgljbGFzcyBDIDogcHVibGljIEJhc2V7CglwdWJsaWM6CgkJdm9pZCBhY2NlcHQoVmlzaXRvciYgdikgb3ZlcnJpZGUKCQl7CgkJCXYudmlzaXQoKnRoaXMpOwoJCX0KCX07CgkKCWNsYXNzIENvbGxlY3Rpb25PZkJhc2UKCXsKCXB1YmxpYzoKCQl2b2lkIGFkZCAoc3RkOjpzaGFyZWRfcHRyPEJhc2U+IGl0ZW0pe21faXRlbXMucHVzaF9iYWNrKGl0ZW0pO30KCQlzdGQ6OnZlY3RvcjxzdGQ6OnNoYXJlZF9wdHI8QmFzZT4+IGNvbnN0JiBnZXRJdGVtcygpIGNvbnN0IHtyZXR1cm4gbV9pdGVtczt9CgkKCXByaXZhdGU6CgkJc3RkOjp2ZWN0b3I8c3RkOjpzaGFyZWRfcHRyPEJhc2U+PiBtX2l0ZW1zOwoJfTsKCQogICAgaW50IG1haW4oKQoJewoJCXVzaW5nIG5hbWVzcGFjZSBzdGQ7CgkKCQlDb2xsZWN0aW9uT2ZCYXNlIGNvbGxlY3Rpb247CgkKCQljb2xsZWN0aW9uLmFkZChtYWtlX3NoYXJlZDxBPigpKTsKCQljb2xsZWN0aW9uLmFkZChtYWtlX3NoYXJlZDxBPigpKTsKCQljb2xsZWN0aW9uLmFkZChtYWtlX3NoYXJlZDxDPigpKTsKCQljb2xsZWN0aW9uLmFkZChtYWtlX3NoYXJlZDxCPigpKTsKCQoJCVZpc2l0b3IgdjsKCQlmb3IgKGF1dG8gY29uc3QmIHggOiBjb2xsZWN0aW9uLmdldEl0ZW1zKCkpCgkJewoJCQl4LT5hY2NlcHQodik7CgkJfQoJCS8qCgkJVGhlIGRlc2lyZWQgb3V0cHV0IG9mIHRoaXMgbG9vcCBzaG91bGQgYmU6CgkJCgkJQQoJCUEKCQlDCgkJQgoJCQoJCSovCgkJCgkJcmV0dXJuIDA7Cgl9Cgo=