    #include <iostream>
	#include <memory>
	#include <vector>
	
	class Base {};
	class A : public Base{};
	class B : public Base{};
	class C : public Base{};
	
	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;
	};
	
	void identify( std::shared_ptr<A> const& )
	{
		std::cout << "A" << std::endl;
	}
	
	void identify( std::shared_ptr<B> const& )
	{
		std::cout << "B" << std::endl;
	}
	
	void identify( std::shared_ptr<C> const& )
	{
		std::cout << "C" << std::endl;
	}
	
	//This function works in the below for loop, but this is not what I need to use
	void identify( std::shared_ptr<Base> const& )
    {
	 	std::cout << "Base" << std::endl;
	}
	
	
    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>());
	
		for (auto const& x : collection.getItems())
		{
			// THE QUESTION:
			// How to distinguish different type of items
			// to invoke "identify" with object specific signatures ???
			// Can I cast somehow the object types that I push_back on my vector ???
	
			identify(x);
		}
		/*
		The desired output of this loop should be:
		
		A
		A
		C
		B
		
		*/
		
		return 0;
	}

