[C++11] 对不同类别不定参数的ForEach

本文实现以下功能,在VS2013上编译通过 (VS2012编译不过)


struct MyProcesser
{
template<int Index /*编译期索引值*/, int Count, typename T>
static // <-static是可选的
inline void process(const T& t)
{
 std::cout << "■index:"<< Index << "  type:" << typeid(t).name() << "  value:" << t << "■"<<std::endl;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
TupleForEach::foreach<MyProcesser>(std::make_tuple("0", std::string("str"), 2.0, 3), &MyProcesser());
TupleForEach::foreach_reverse<MyProcesser>(std::make_tuple("0", std::string("str"), 2.0, 3));

//  GetNumbers<5>::Tuple tuple_Of_Numbers5; //tuple<Number<0>,Number<1>, ... Number<4>>
//  GetNumbers<3>::type Numbers0to2;  //Numbers<0,1,2>

return 0;
}


支持代码(可以放头文件)
#include <tuple>
struct _NumbersHelper
{
	//  SNumber<4> 这样的类,把编译期int常量包装成类
	template<int N>
	struct SNumber
	{
		enum { value = N };
	};

	//  SNumbers<0,1,2,3,4,5,6> 这样的类
	template<int... Args>
	class SNumbers
	{
	};

	//  GetTupleOfNumbers(std::tuple<>, 数字的个数)    ->   std::tuple<SNumber<0>, SNumber<1> , ... SNumber<Count-1> >
	template <typename Tuple, int Count, class = std::enable_if<(std::tuple_size<Tuple>::value == Count)>::type >
	static auto GetTupleOfNumbers() -> Tuple;
	template <typename Tuple, int Count, class = std::enable_if<(std::tuple_size<Tuple>::value < Count)>::type >
	static auto GetTupleOfNumbers()-> decltype(GetTupleOfNumbers<typename std::_Tuple_cat1<Tuple, std::tuple<SNumber<std::tuple_size<Tuple>::value>>>::type, Count>());

	//  GetNumberFromTuple(std::tuple<SNumber<0>, SNumber<1>, ... >)    ->   SNumbers<0, 1, ...>
	template<typename... Args>
	static auto GetNumberFromTuple(std::tuple<Args...>*)->SNumbers < Args::value ... > ;

	//  GetNumbers<Count>::type  ->   SNumber<0, 1, 2, ..., Count-1>
	template<int Count>
	struct GetNumbers
	{
		typedef decltype(GetTupleOfNumbers<std::tuple<>, Count>()) Tuple;
		typedef decltype(GetNumberFromTuple((Tuple*)0)) type;
	};
};
namespace TupleForEach
{
	//内循环,根据索引进行调用Processer的process函数,兼容static
	template <typename Processer, typename Tuple, int... Indexes>
	inline void _foreach(Tuple& values, _NumbersHelper::SNumbers<Indexes...>*, Processer* p = NULL)
	{
		enum { TupleSize = std::tuple_size<Tuple>::value };
		bool n[] = { (p->process<Indexes, TupleSize>(std::get<Indexes>(values)), false)... };
	}
	//外嵌套用于把索引展开
	template <typename Processer, typename Tuple>
	inline void foreach(Tuple& values, Processer* p = NULL)
	{
		enum { TupleSize = std::tuple_size<Tuple>::value };
		return _foreach<Processer>(values, (_NumbersHelper::GetNumbers<TupleSize>::type*)0, p);
	}
	
	//内循环,根据索引进行调用Processer的process函数,兼容static
	template <typename Processer, typename Tuple, int... Indexes>
	inline void _foreach_reverse(Tuple& values, _NumbersHelper::SNumbers<Indexes...>*, Processer* p = NULL)
	{
		enum { TupleSize = std::tuple_size<Tuple>::value };
		bool n[] = { (p->process<TupleSize - Indexes - 1, TupleSize>(std::get<TupleSize - Indexes - 1>(values)), false)... };
	}
	//外嵌套用于把索引展开
	template <typename Processer, typename Tuple>
	inline void foreach_reverse(Tuple& values, Processer* p = NULL)
	{
		enum { TupleSize = std::tuple_size<Tuple>::value };
		return _foreach_reverse<Processer>(values, (_NumbersHelper::GetNumbers<TupleSize>::type*)0, p);
	}
}




你可能感兴趣的:(Tuple,C++11,可变参数,VS2013)