    #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;
	}

