#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

struct Trace
{
	Trace() 						{ cout << "X()\n"; }
	~Trace() 						{ cout << "~X()\n"; }
	Trace(Trace const &)			{ cout << "X(X&)\n"; }
	Trace(Trace&&)					{ cout << "X(X&&)\n"; }
	void operator=(Trace const &) 	{ cout << "X::op=(X&)\n"; }
	void operator=(Trace &&) 		{ cout << "X::op=(X&&)\n"; }
};

struct Big
{
	vector<int> vec;
	Big(size_t n): vec(n) {}
	bool operator<(Big const &r) const { return vec.size() < r.vec.size(); }

	Trace trace;
};

template<typename T>
T mmin( std::initializer_list<T> x )
{
	return * std::min_element( x.begin(), x.end() );
}

template<typename T, typename... Args> T vmin( T arg1, Args&&... args )
{
	T *p[] = { &arg1, &args... };

	return **std::min_element( begin(p), end(p), 
				[](T *a, T *b) { return *a < *b; } );
}

Big make_big(size_t n) { return Big(n); }

int main()
{
	Big a(100), b(200);

	Big const &t = 
	//min<Big>({ make_big(400), b , a , make_big(600) })
	//mmin<Big>({ make_big(400), b , a , make_big(600) })
	vmin<Big>( make_big(400), b , a , make_big(600) )
	;

	cout << t.vec.size() << endl;
}
