#include <iostream>
#include <memory>

template <typename T>
struct Array
{
	T& operator[](size_t i) const
	{
		auto current_node = node;
		for (size_t j(0); j != i; ++j)
			current_node = current_node->next;
		return current_node->value;
	}
	Array<T>& operator<<(const T& n)
	{
		if (node) {
			auto current_node = node;
			while(current_node->next)
				current_node = current_node->next;
			current_node->next = std::make_shared<Node>(n);
		}
		else
			node = std::make_shared<Node>(n);
		return *this;
	}
	friend std::ostream& operator <<(std::ostream &stream, const Array<T>& array)
	{
		auto current_node = array.node;
		do {
			stream << current_node->value << ", ";
			current_node = current_node->next;
		} while(current_node->next);
		stream << current_node->value << std::endl;
		return stream;
	}
private:
	struct Node
	{
		Node(const T& n) : value(n) {}
		T value;
		std::shared_ptr<Node> next;
	};
	std::shared_ptr<Node> node;
};

int main() {
	Array<int> array;

	array << 1;
	array << 4;
	array << 8 << 8;

	std::cout << array;

	return 0;
}
