考虑这些类:
C1< C2< C3< ......< Cn,Ci< Cj表示sizeof(Ci)<的sizeof(CJ) 我想要一个使用可变参数模板作为Ci序列的结构,OrderBySize< AnySequenceOfCis>,例如:OrderBySize< C1,C2,C3,...,Cn>要么
OrderBySize< C2,C1,C4,…,CN> ……所有可能的组合
并给出以下结构:
class result{ Cn elem1; Cn-1 elem2; . . . C1 elemn;}
我读了this article,它显示了我们如何定义元组< typename ... T>然而,这是不同的,更难以实现并且非常有用.
编辑:
order_by_size< T1,Tn>将包含T1,Tn的有序组合的元组
但是我不希望用户知道我在命令字段,用户会像元组一样使用它.因此,为了访问字段,用户将使用:
template< typename ... Tn>
获取< size_t>(const MyStructure< Tn ...& m)获取size_t'th元素,该元素在新元组中具有另一个索引.
template <typename...>struct typeList { using type = typeList;};
我将假设一组非常短的元函数(头部,尾部,连续,大小).为简洁起见,我将省略它们.
所以让我们跳进编写合并排序:
template <typename TL,typename Cmp = LessSize>struct sort{ using left_right = typename split<TL,size<TL>::value/2>::type; using left = typename sort<head_t<left_right>,Cmp>::type; using right = typename sort<head_t<tail_t<left_right>>,Cmp>::type; using type = typename merge<left,right,Cmp>::type;};// base case for exactly 1 elementtemplate <typename T,typename Cmp>struct sort<typeList<T>,Cmp> { using type = typeList<T>;};// potentially add a base case for exactly 2 elements here?
这里的一般结构看起来应该很熟悉.我们将我们的类型列表TL分成两个相等的部分,对它们进行排序,然后合并.当然,这是元编程,因此一切都不必要地复杂化.
让我们从拆分开始吧. split接受一个类型列表和一个大小,并返回两个类型列表的类型列表:第一个具有给定的大小,第二个是余数:
template <typename A,typename B,size_t N>struct split_impl : std::conditional< size<A>::value < N,split_impl<concat_t<A,typeList<head_t<B>>>,tail_t<B>,N>,typeList<A,B> >::type{ };template <typename TL,size_t N>struct split : split_impl<typeList<>,TL,N>{ };
所以这给了我们左右(至少一次我们应用head_t<>和head_t< tail_t<>>).剩下的就是合并步骤.我正在使用Boost MPL关于元函数类的概念,所以LessSize是:
struct LessSize { template <typename A,typename B> using apply = std::integral_constant<bool,sizeof(A) < sizeof(B)>;};
merge只需要遍历两个类型列表,并根据两个类型列表之间的比较器选择最小元素.首先,我们将从所有基本情况开始:
template <typename L,typename R,typename Cmp>struct merge;// R emptytemplate <typename... T,typename Cmp>struct merge<typeList<T...>,typeList<>,Cmp> { using type = typeList<T...>;};// L emptytemplate <typename... T,typename Cmp>struct merge<typeList<>,typeList<T...>,Cmp> { using type = typeList<T...>;};
然后是递归步骤,这有点难看:
template <typename A,typename... As,typename... Bs,typename Cmp> struct merge<typeList<A,As...>,typeList<B,Bs...>,Cmp>: std::conditional< Cmp::template apply<A,B>::value,concat_t<typeList<A>,typename merge<typeList<As...>,Cmp>::type>,concat_t<typeList<B>,typename merge<typeList<A,typeList<Bs...>,Cmp>::type> >::type{ };
基本上,给定两个类型列表{A,As …}和{B,Bs …},我们选择基于Cmp的最小值,这就是我们从中d出元素的一面.如果Cmp :: apply< A,B>,那么我们将A与{As …}与{B,Bs …}合并的结果连接起来.反之亦然.
这就是她写的全部内容:
template <typename T>struct TD;int main(){ using T = sort<typeList<int,double,char,float>,LessSize>::type; TD<T> r;}main.cpp: In function 'int main()':main.cpp:131:11: error: aggregate 'TD<typeList<char,float,int,double> > r' has incomplete type and cannot be defined TD<T> r; ^
一旦你有了排序类型,制作一个元组很简单:
template <template <typename...> class C>struct Meta_quote { template <typename... T> using apply = C<T...>;};template <typename F,typename TL>struct Meta_apply;template <typename F,typename... T>struct Meta_apply<F,typeList<T...>> { using type = typename F::template apply<T...>;};template <typename... T>struct my_tuple: Meta_apply<Meta_quote<std::tuple>,typename sort<typeList<T...>>::type >::type;{ using base_tuple = Meta_apply<...>;};
现在只需为get<>添加重载on my_tuple< T ...>:
template <size_t I,typename... T>auto get(my_tuple<T...>& t) { using type = std::tuple_element_t<I,std::tuple<T...>>; return std::get<type>(static_cast<typename my_tuple<T...>::base_type&>(t));}总结
以上是内存溢出为你收集整理的c – 按大小存储字段的结构全部内容,希望文章能够帮你解决c – 按大小存储字段的结构所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)