#include <iostream>
#include <vector>
#include <set>
#include <array>
using namespace std;

template<typename T>
size_t metaSizeOf(const T& t)
{
	return sizeof(T);
}

// Pre-declarations, otherwise some resolutions could be missing
template<typename T, typename Alloc, template <typename, typename> class V>
size_t metaSizeOf(const V<T, Alloc>& v);
template<typename T, typename Compare, typename Alloc, template <typename, typename, typename> class V>
size_t metaSizeOf(const V<T, Compare, Alloc>& v);
template<typename Key, typename Val, typename Compare, typename Alloc, template <typename, typename, typename, typename> class V>
size_t metaSizeOf(const V<Key, Val, Compare, Alloc>& v);
template<typename T, std::size_t N, template <typename, std::size_t> class V>
size_t metaSizeOf(const V<T, N>& v);
template<typename T, std::size_t N>
size_t metaSizeOf(const std::array<T, N>&);


// Implementation for std::vector, std::list, std::deque, etc.
template<typename T, typename Alloc, template <typename, typename> class V>
size_t metaSizeOf(const V<T, Alloc>& v)
{
	size_t bytes = sizeof(V<T, Alloc>);
	for(const auto& t: v) bytes += metaSizeOf(t);
	return bytes;
}

// Implementation for std::set, std::multiset, etc.
template<typename T, typename Compare, typename Alloc, template <typename, typename, typename> class V>
size_t metaSizeOf(const V<T, Compare, Alloc>& v)
{
	size_t bytes = sizeof(V<T, Compare, Alloc>);
	for(const auto& t: v) bytes += metaSizeOf(t);
	return bytes;
}

// Implementation for std::map, std::multimap, etc.
template<typename Key, typename Val, typename Compare, typename Alloc, template <typename, typename, typename, typename> class V>
size_t metaSizeOf(const V<Key, Val, Compare, Alloc>& v)
{
	size_t bytes = sizeof(V<Key, Val, Compare, Alloc>);
	for(const auto& t: v) bytes += metaSizeOf(t);
	return bytes;
}

// Implementation for std::array-like containers
template<typename T, std::size_t N, template <typename, std::size_t> class V>
size_t metaSizeOf(const V<T, N>& v)
{
	size_t bytes = sizeof(V<T, N>);
	for(const auto& t: v) bytes += metaSizeOf(t);
	return bytes;
}

// Implementation for std::array only
template<typename T, std::size_t N>
size_t metaSizeOf(const std::array<T, N>&)
{
	return sizeof(std::array<T, N>) + N * sizeof(T);
}


int main() {
	std::vector<std::set<std::array<int, 10>>> v;
	// populate v
	std::array<int, 10> a;
	std::set<std::array<int, 10>> s;
	s.insert(a);
	v.push_back(s);
	v.push_back(s);
	
	std::size_t bytes = sizeof(v);
	for(auto& s : v)
	{
	    bytes += sizeof(s);
	
	    for(auto& a : s)
	    {
	        bytes += sizeof(a) + sizeof(int) * 10;
	    }
	}
	
	cout << "The size from for loop is " << bytes << endl;
	cout << "The size from metaSizeOf is " << metaSizeOf(v) << endl;

	return 0;
}