模板练习-tuple的实现(Implementation of template exercise tuple)

#include <iostream>
template <typename... T>
class mytuple
{
  public:
	mytuple(T... t) { std::cout << "hello " << std::endl; }
};

template <>
class mytuple<>
{
};

template <typename HEAD, typename... TLIST>
class mytuple<HEAD, TLIST...> : public mytuple<TLIST...>
{
  public:
	mytuple(HEAD head, TLIST... args) : mytuple<TLIST...>(args...), value(head) { std::cout << "value :" << value << " type:" << typeid(HEAD).name() << std::endl; }

	HEAD value;
};

template <int N, typename... T>
struct mytupleat;

template <int N, typename T, typename... TLIST>
struct mytupleat<N, mytuple<T, TLIST...> >
{
	static_assert(sizeof...(TLIST) >= N, "wrong index");
	typedef typename mytupleat<N - 1, mytuple<TLIST...> >::value_type value_type;
	typedef typename mytupleat<N - 1, mytuple<TLIST...> >::tuple_type tuple_type;
};

template <typename T, typename... TLIST>
struct mytupleat<0, mytuple<T, TLIST...> >
{
	typedef T					 value_type;
	typedef mytuple<T, TLIST...> tuple_type;
};
///////////////////////////////////////////////////////////////////////////
template <int N, typename... TLIST>
decltype(auto) get_tuple_index(mytuple<TLIST...> tuple)
{
	std::cout << sizeof...(TLIST) << std::endl;

	typedef typename mytupleat<N, mytuple<TLIST...> >::value_type VALUE;
	typedef typename mytupleat<N, mytuple<TLIST...> >::tuple_type TUPLE;
	VALUE														  ret = ((TUPLE)tuple).value;
	return ret;
}
///////////////////////////////////////////////////////////////////////////

template <class T>
void pTuple(T t)
{
	std::cout << typeid(T).name() << std::endl;
}

template <class... T>
void pTuplev(T... t)
{
	/// std::cout << typeid(T).name() << std::endl;
	std::cout << sizeof...(T) << std::endl;

	//((std::cout << typeid(t).name() << std::endl), ...);
}

int main()
{
	mytuple<int, double, const char *> test(12, 13.12, "123");

	auto ntest = get_tuple_index<0>(test);

	pTuple(test);
	pTuplev(test);

	// auto dtest	 = mygettuple<1>(test);
	// auto csztest = mygettuple<2>(test);

	// mytuple<int> test2(22);
	// auto		 ntest2 = get_tuple_index<0>(test2);
}

template <class... ARGS>
class Base
{
};

template <class T, class... ARGS>
class Base<T, ARGS...>
{
};

Base<int, double, char> base;
————————
#include <iostream>
template <typename... T>
class mytuple
{
  public:
	mytuple(T... t) { std::cout << "hello " << std::endl; }
};

template <>
class mytuple<>
{
};

template <typename HEAD, typename... TLIST>
class mytuple<HEAD, TLIST...> : public mytuple<TLIST...>
{
  public:
	mytuple(HEAD head, TLIST... args) : mytuple<TLIST...>(args...), value(head) { std::cout << "value :" << value << " type:" << typeid(HEAD).name() << std::endl; }

	HEAD value;
};

template <int N, typename... T>
struct mytupleat;

template <int N, typename T, typename... TLIST>
struct mytupleat<N, mytuple<T, TLIST...> >
{
	static_assert(sizeof...(TLIST) >= N, "wrong index");
	typedef typename mytupleat<N - 1, mytuple<TLIST...> >::value_type value_type;
	typedef typename mytupleat<N - 1, mytuple<TLIST...> >::tuple_type tuple_type;
};

template <typename T, typename... TLIST>
struct mytupleat<0, mytuple<T, TLIST...> >
{
	typedef T					 value_type;
	typedef mytuple<T, TLIST...> tuple_type;
};
///////////////////////////////////////////////////////////////////////////
template <int N, typename... TLIST>
decltype(auto) get_tuple_index(mytuple<TLIST...> tuple)
{
	std::cout << sizeof...(TLIST) << std::endl;

	typedef typename mytupleat<N, mytuple<TLIST...> >::value_type VALUE;
	typedef typename mytupleat<N, mytuple<TLIST...> >::tuple_type TUPLE;
	VALUE														  ret = ((TUPLE)tuple).value;
	return ret;
}
///////////////////////////////////////////////////////////////////////////

template <class T>
void pTuple(T t)
{
	std::cout << typeid(T).name() << std::endl;
}

template <class... T>
void pTuplev(T... t)
{
	/// std::cout << typeid(T).name() << std::endl;
	std::cout << sizeof...(T) << std::endl;

	//((std::cout << typeid(t).name() << std::endl), ...);
}

int main()
{
	mytuple<int, double, const char *> test(12, 13.12, "123");

	auto ntest = get_tuple_index<0>(test);

	pTuple(test);
	pTuplev(test);

	// auto dtest	 = mygettuple<1>(test);
	// auto csztest = mygettuple<2>(test);

	// mytuple<int> test2(22);
	// auto		 ntest2 = get_tuple_index<0>(test2);
}

template <class... ARGS>
class Base
{
};

template <class T, class... ARGS>
class Base<T, ARGS...>
{
};

Base<int, double, char> base;