如何实现在C++编译期检查tuple的空间布局顺序是否达到了最省内存的对象?

发布日期:2018-06-08 来源:财富国际在线 阅读:
如何实现在C++编译期检查tuple的空间布局顺序是否达到了最省内存的对象? vczh 2小时前 179 sizeof 编译程序 我们知道std::tuple之流,由于类型对齐的缘故,他的字段排列顺序会影响到最终这个tuple的sizeof。所以在实现tuple时,优化字段排列顺序是有意义的。为了简单化问题,我们先假设每一个字段大小都是2的幂并且不超过16,并且都按自己的大小来对齐。例如在x64 sizeof(long double)=16, 然后他就按照16字节来对齐。如果我们把这每个字段的size都放到一个数组里a[n],那么现在建模后的问题来了:问题1:对于tuple size数组S[n], 我们定…
0 0
其他回答
tuple一般是个便捷的临时存在。
就像ls说的, 不是临时处理的话,直接再声明个 struct 用名字来访问, 而不是用tuple的序号。
王杰 2小时前 0条评论
0 0

你可以用模板元编程枚举类型参数的全排列,挨个求sizeof(tuple<?>),然后static_assert看看最小值跟你手上的那个是否一致。YiL财富国际

下面的程序可以打印出,给定类型的前提下,tuple尺寸最小的其中一个顺序:YiL财富国际

main函数:YiL财富国际

int main(int argc, char **argv){	using candidates = _map_t<to_tuple_and_size::f, _perm_of_t<		/* 把你的类型放这里 */		bool, double, short, int, char	>>;	constexpr int min_size = min_of<_map_t<second::f, candidates>>::value;	cout << typeid(head_of<filter_tuple<min_size, candidates>::type>::type).name() << endl;	return 0;}

运行结果:YiL财富国际

class std::tuple<double,int,short,bool,char>

代码:YiL财富国际

#include <tuple>#include <type_traits>#include <typeinfo>#include <iostream>using namespace std;namespace fuck{#define BEGIN_FUNC								/	template<typename T>						/	struct g;									/#define END_FUNC								/	struct f									/	{											/		template<typename T>					/		struct apply							/		{										/			using type = typename g<T>::type;	/		};										/	};											/	// _list, _val, _val_of	template<typename ...T>	struct _list;	template<int Value>	struct _val;	template<typename T>	struct _val_of;	template<int Value>	struct _val_of<_val<Value>>	{		static const int value = Value;	};	// _concat_t	template<typename T, typename U>	struct _concat;	template<typename ...T, typename  ...U>	struct _concat<_list<T...>, _list<U...>>	{		using type = _list<T..., U...>;	};	template<typename T, typename U>	using _concat_t = typename _concat<T, U>::type;	// _join_t	template<typename ...T>	struct _join;	template<>	struct _join<>	{		using type = _list<>;	};	template<typename T, typename ...U>	struct _join<T, U...>	{		using type = _concat_t<T, typename _join<U...>::type>;	};	template<typename ...T>	using _join_t = typename _join<T...>::type;	// _map_t	template<typename F, typename Ts>	struct _map;	template<typename F>	struct _map<F, _list<>>	{		using type = _list<>;	};	template<typename F, typename T, typename ...U>	struct _map<F, _list<T, U...>>	{		using type = _concat_t<_list<typename F::template apply<T>::type>, typename _map<F, _list<U...>>::type>;	};	template<typename F, typename Ts>	using _map_t = typename _map<F, Ts>::type;	// _unpack_t	template<template<typename...> class F, typename Ts>	struct _unpack;	template<template<typename...> class F, typename ...T>	struct _unpack<F, _list<T...>>	{		using type = F<T...>;	};	template<template<typename...> class F, typename Ts>	using _unpack_t = typename _unpack<F, Ts>::type;	// _map_join_t	template<typename F, typename Ts>	using _map_join_t = _unpack_t<_join_t, _map_t<F, Ts>>;	// _pick_to_fronts_t	template<typename T, typename U>	struct _pick_to_fronts;	template<typename T>	struct _pick_to_fronts<T, _list<>>	{		using type = _list<>;	};	template<typename T, typename U, typename ...V>	struct _pick_to_fronts<T, _list<U, V...>>	{		using type = _concat_t<			_list<_join_t<_list<U>, T, _list<V...>>>,			typename _pick_to_fronts<_concat_t<T, _list<U>>, _list<V...>>::type		>;	};	template<typename ...T>	using _pick_to_fronts_t = typename _pick_to_fronts<_list<>, _list<T...>>::type;	// _perm_of	namespace _head_split	{		BEGIN_FUNC		template<typename T, typename ...U>		struct g<_list<T, U...>>		{			using type = _list<T, _list<U...>>;		};		END_FUNC	}	namespace _head_merge	{		BEGIN_FUNC		template<typename T, typename ...U>		struct g<_list<T, _list<U...>>>		{			using type = _list<T, U...>;		};		END_FUNC	}	template<typename T>	struct _insert_at_head	{		template<typename U>		struct apply		{			using type = _concat_t<_list<T>, U>;		};	};	template<typename T>	struct _perm_of;	namespace _partial_perm	{		BEGIN_FUNC		template<typename T, typename U>		struct g<_list<T, U>>		{			using perm_of_U_t = typename _perm_of<U>::type;			using type = _map_t<_insert_at_head<T>, perm_of_U_t>;		};		END_FUNC	}	template<>	struct _perm_of<_list<>>	{		using type = _list<>;	};	template<typename T>	struct _perm_of<_list<T>>	{		using type = _list<_list<T>>;	};	template<typename ...T>	struct _perm_of<_list<T...>>	{		using fronts_t = _pick_to_fronts_t<T...>;		using head_pairs_t = _map_t<_head_split::f, fronts_t>;		using type = _map_join_t<_partial_perm::f, head_pairs_t>;	};	template<typename ...T>	using _perm_of_t = typename _perm_of<_list<T...>>::type;}using namespace fuck;namespace test{	struct inc	{		template<typename T>		struct apply		{			using type = _val<_val_of<T>::value + 1>;		};	};	struct this_and_next	{		template<typename T>		struct apply		{			using type = _list<T, typename inc::apply<T>::type>;		};	};	template<typename T, typename U>	inline T* same()	{		return static_cast<U*>(nullptr);	}}using namespace test;void Test(){	same<		_concat_t<_list<>, _list<>>,		_list<>	>();	same<		_concat_t<_list<>, _list<_val<1>, _val<2>>>,		_list<_val<1>, _val<2>>	>();	same<		_concat_t<_list<>, _list<_val<1>, _val<2>>>,		_list<_val<1>, _val<2>>	>();	same<		_concat_t<_list<_val<1>, _val<2>>, _list<>>,		_list<_val<1>, _val<2>>	>();	same<		_concat_t<_list<_val<1>, _val<2>>, _list<_val<3>, _val<4>>>,		_list<_val<1>, _val<2>, _val<3>, _val<4>>	>();	same<		_join_t<_list<>, _list<>, _list<>>,		_list<>	>();	same<		_join_t<_list<_val<1>>, _list<_val<2>, _val<3>>, _list<_val<4>, _val<5>, _val<6>>>,		_list<_val<1>, _val<2>, _val<3>, _val<4>, _val<5>, _val<6>>	>();	same<		_map_t<inc, _list<_val<1>, _val<2>, _val<3>>>,		_list<_val<2>, _val<3>, _val<4>>	>();	same<		_map_join_t<this_and_next, _list<_val<1>, _val<2>, _val<3>>>,		_list<_val<1>, _val<2>, _val<2>, _val<3>, _val<3>, _val<4>>	>();	same<		_pick_to_fronts_t<>,		_list<>	>();	same<		_pick_to_fronts_t<_val<1>>,		_list<_list<_val<1>>>	>();	same<		_pick_to_fronts_t<_val<1>, _val<2>>,		_list<_list<_val<1>, _val<2>>, _list<_val<2>, _val<1>>>	>();	same<		_pick_to_fronts_t<_val<1>, _val<2>, _val<3>>,		_list<			_list<_val<1>, _val<2>, _val<3>>,			_list<_val<2>, _val<1>, _val<3>>,			_list<_val<3>, _val<1>, _val<2>>		>	>();	same<		_perm_of_t<>,		_list<>	>();	same<		_perm_of_t<_val<1>>,		_list<_list<_val<1>>>	>();	same<		_perm_of_t<_val<1>, _val<2>>,		_list<_list<_val<1>, _val<2>>, _list<_val<2>, _val<1>>>	>();	same<		_perm_of_t<_val<1>, _val<2>, _val<3>>,		_list<			_list<_val<1>, _val<2>, _val<3>>,			_list<_val<1>, _val<3>, _val<2>>,			_list<_val<2>, _val<1>, _val<3>>,			_list<_val<2>, _val<3>, _val<1>>,			_list<_val<3>, _val<1>, _val<2>>,			_list<_val<3>, _val<2>, _val<1>>		>	>();}namespace first{	BEGIN_FUNC	template<typename T, typename U>	struct g<_list<T, U>>	{		using type = T;	};	END_FUNC}namespace second{	BEGIN_FUNC	template<typename T, typename U>	struct g<_list<T, U>>	{		using type = U;	};	END_FUNC}namespace to_tuple_and_size{	BEGIN_FUNC	template<typename ...T>	struct g<_list<T...>>	{		using type = _list<tuple<T...>, _val<sizeof(tuple<T...>)>>;	};	END_FUNC}template<typename ...T>struct min_of;template<int Value>struct min_of<_list<_val<Value>>>{	static const int value = Value;};template<int Value, typename ...T>struct min_of<_list<_val<Value>, T...>>{	static const int min_of_the_rest = min_of<_list<T...>>::value;	static const int value = Value < min_of_the_rest ? Value : min_of_the_rest;};template<int Value, typename Ts>struct filter_tuple;template<int Value>struct filter_tuple<Value, _list<>>{	using type = _list<>;};template<int Expected, typename T, typename ...Ts>struct filter_tuple<Expected, _list<_list<T, _val<Expected>>, Ts...>>{	using type = _concat_t<_list<T>, typename filter_tuple<Expected, _list<Ts...>>::type>;};template<int Expected, int Actual, typename T, typename ...Ts>struct filter_tuple<Expected, _list<_list<T, _val<Actual>>, Ts...>>{	using type = typename filter_tuple<Expected, _list<Ts...>>::type;};template<typename T>struct head_of;template<typename T, typename ...U>struct head_of<_list<T, U...>>{	using type = T;};int main(int argc, char **argv){	using candidates = _map_t<to_tuple_and_size::f, _perm_of_t<bool, double, short, int, char>>;	constexpr int min_size = min_of<_map_t<second::f, candidates>>::value;	cout << typeid(head_of<filter_tuple<min_size, candidates>::type>::type).name() << endl;	return 0;}
vczh 2小时前 0条评论
0 0

关于我们 联系我们招聘信息免责申明广告服务 网站地图 百度地图 TAG标签

Copyright@2018-2022 Cfgjzx.Com 财富国际在线 版权所有 All Rights Reserved   
财富国际提供:最新财富资讯、房产资讯、股票资讯、区块链、投资理财、保险导购、健康产品、公私募基金,易经等资讯及服务.