C++元编程——模板容器类

元编程中有时候会需要容器已容纳暂时的数据。已经在模板元编程上卷了一周,结果发现这种编程方式有提高运行效率的作用,但是在编译时间长、执行文件大、编程复杂的缺点下实在是非常鸡肋,除了炫技几乎可以说毫无作用。所以就炫技一下,以下实现了一种支持插入、连接、交换元素的类模板,本意是用来进一步写行列式求值运算的。代码如下:

template<int...is>
struct container
{
	template<int N, int itr, int topop, int... remains>
	static constexpr int get_cal = get_cal<N, itr + 1, remains...>;

	template<int N, int ret, int...remains>
	static constexpr int get_cal<N, N, ret, remains...> = ret;

	template<int N>
	static constexpr int get = get_cal<N, 0, is...>;

	static constexpr int size = sizeof...(is);

	template<int i> using push_back = container<is..., i>;

	template<int i> using push_front = container<i, is...>;

	template<int total_N, int cur_N, typename other>
	struct st_push_other_back
	{
		using t_next = push_back < other::template get<cur_N>>;
		using ret = typename t_next::template st_push_other_back<total_N, cur_N + 1, other>::ret;
	};

	template<int N, typename other>
	struct st_push_other_back<N, N, other>
	{
		using ret = container<is...>;
	};
	template<typename other>
	using push_other_back = typename st_push_other_back<other::size, 0, other>::ret;

	template<int N, int top, int...remains>
	struct n_cal
	{
		using t_front = typename n_cal<N - 1, remains...>::t_front::template push_front<top>;
		using t_after = typename n_cal<N - 1, remains...>::t_after;
	};

	template<int top, int...remains>
	struct n_cal<1, top, remains...>
	{
		using t_front = container<top>;
		using t_after = container<remains...>;
	};

	/* 当is时空的时候短路n_cal运算 */
	template<bool b, int N>
	struct enable_cal 
	{
		using front = typename n_cal<N, is...>::t_front;
		using after = typename n_cal<N, is...>::t_after;
	};

	template<int N>
	struct enable_cal<false, N>
	{
		using front = container<>;
		using after = container<>;
	};

	template<int N>
	using front_n = typename enable_cal<sizeof...(is)!=0, N>::front;

	template<int N>
	using after_n = typename enable_cal<sizeof...(is) != 0, N>::after;

	template<int N, int M>
	using mid_nm = typename front_n<M>::template after_n<N>;

	template<int N, int M>
	struct swap_cal 
	{
		using swap_front = front_n<N>;
		using swap_mid = mid_nm<N + 1, M>;
		using swap_after = after_n<M + 1>;
		using ret = typename swap_front::template push_back<get<M>>::template push_other_back<swap_mid>::template push_back<get<N>>::template push_other_back<swap_after>;
	};

	template<int N, int M>
	using swap = typename swap_cal<N, M>::ret;

};

下面采用一个测试程序来验证这种模板的有效性:

/* 生成序列 */
template<int N, int cur_i, int... is>
struct gen_seq 
{
	using t = typename gen_seq<N, 1+cur_i, is..., cur_i>::t;
};

template<int N, int... is>
struct gen_seq<N, N, is...>
{
	using t = container<is...>;
};

template<int N>
using gen_seq_t = typename gen_seq<N, 0>::t;

int main() 
{
	gen_seq_t<10>::push_other_back<gen_seq_t<2>> k;
	decltype(k)::mid_nm<1, 10>::swap<1,2> j;
	int i = k.get<3>;
	int ik = k.get<k.size-1>;
	_getch();
	return 0;
}

通过调试,可以发现k的类型为container<0,1,2,3,4,5,6,7,8,9,0,1>。可见已经将container<0,...,9>和container<0,1>连接了起来。通过get获取到的i等于2,也正确获取对应位置的参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腾昵猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值