Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 按大小存储字段的结构_C++_Templates_C++11_Struct_Variadic Templates - Fatal编程技术网

C++ 按大小存储字段的结构

C++ 按大小存储字段的结构,c++,templates,c++11,struct,variadic-templates,C++,Templates,C++11,Struct,Variadic Templates,我想知道如何在C++中执行以下操作: 考虑以下类别: C1

我想知道如何在C++中执行以下操作:

考虑以下类别:

C1
Ci
表示
sizeof(Ci)

我想要一个使用可变模板作为
Ci
序列的结构

OrderBySize,它显示了我们如何定义一个
元组
,然而,这是不同的,更难实现,而且非常有用

编辑:

order\u by\u size
包含
T1,…,Tn的有序组合的元组

但是,我不想让用户知道我正在对字段排序,用户会像使用元组一样使用它。因此,为了访问字段,用户将使用:

模板
get(const MyStructure&m)
获取新的
元组中有其他索引的
大小\u t
元素


这可能不是最有效的实现(它使用类型的循环排列来确定具有最大大小的类型),并且可能包含错误,但整个想法应该是清楚的。结果是
std::tuple
,类型按大小降序排列。main函数检查它是否实际工作(它在我的gcc-4.8.2上工作)

#包括
#包括
#包括
constexpr std::size\u t max(std::size\u t x,std::size\u t y)
{
返回(x
结构最大尺寸<>
{
静态constexpr std::size\u t result=0;
};
模板
结构最大尺寸
{
静态constexpr std::size\u t result=max(sizeof(t),max\u size::result);
};
模板
按大小排列的结构顺序;
模板
按大小排列的结构顺序;
模板
按大小排列的结构顺序辅助对象
:按大小订购
{ };
模板
按大小排列的结构顺序辅助对象
:按大小订购
{ };
模板
结构顺序按大小执行
:order_by_size_helper=max_size::result,std::tuple,T,Ts..>
{ };
模板
结构顺序按大小执行
{
typedef std::元组结果;
};
模板
按大小排列的结构顺序
:按大小订购
{ };
结构测试
{
std::uint8_t数据[128];
};
模板
布尔检查(R常量和R)
{
返回std::is_same::value;
}
int main()
{
按大小排序:结果r;

std::cout基本上,这个问题归结为根据给定的比较器对类型列表进行排序。一旦有了比较器,其他一切都会随之发生。因此,这个答案只是排序部分。我们将从类型列表开始:

template <typename...>
struct typelist {
    using type = typelist;
};
这里的一般结构看起来应该很熟悉。我们将类型列表,
TL
,分成两个相等的部分,对它们进行排序,然后合并。当然,这是元编程,所以一切都不必要地复杂

让我们从
split
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>
{ };
merge
只需遍历两个类型列表,并根据两个类型列表之间的比较器选择最小的元素。首先,我们将从所有基本情况开始:

template <typename L, typename R, typename Cmp>
struct merge;

// R empty
template <typename... T, typename Cmp>
struct merge<typelist<T...>, typelist<>, Cmp> {
    using type = typelist<T...>;
};

// L empty
template <typename... T, typename Cmp>
struct merge<typelist<>, typelist<T...>, Cmp> {
    using type = typelist<T...>;
};
获得排序类型后,创建元组就很简单了:

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<...>;
};
模板
结构元引号{
模板
使用apply=C;
};
模板
结构元应用;
模板
结构元应用{
使用type=typename F::模板应用;
};
模板
构造我的元组
:meta_apply::type;
{ 
使用基本元组=元应用;
};
现在只需为
my\u tuple
上的
get
添加重载:

模板
自动获取(my_tuple&t){
使用type=std::tuple\u元素\u t;
返回std::get(static_cast(t));
}

Thank's,太好了!我如何使
get
返回适当的字段(按照用户给定的顺序),例如在您的测试中,
get(r)
将返回一个
std::uint32\u t
,而不是
std::uint64\u t
。我想我必须跟踪第一个订单才能这样做,但我看不到how@OthmanBenchekroun你能再多写一点吗,可能有一些例子吗?我不清楚你在问什么。仍然不清楚。展示这个的示例用法,包括通过用户访问-定义的顺序和按排序的顺序。哦,我明白为什么不清楚了。实际上,我希望order\u by\u size是包含数据的结构,而不仅仅是包含元组定义的空结构。为了访问我的
order\u by\u size struct
,我将有一个函数
get
,它的工作方式有点像
std::get
仍然不清楚。这个
get
应该以什么顺序工作?按照用户声明变量时给出的顺序是的,这是一个冗长的答案,甚至省略了很多代码。不过,解决起来很有趣:)哦,天啊,这太神奇了,我明白为什么它很有趣了(我不是在开玩笑)
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>
{ };
struct LessSize {
    template <typename A, typename B>
    using apply = std::integral_constant<bool, sizeof(A) < sizeof(B)>;
};
template <typename L, typename R, typename Cmp>
struct merge;

// R empty
template <typename... T, typename Cmp>
struct merge<typelist<T...>, typelist<>, Cmp> {
    using type = typelist<T...>;
};

// L empty
template <typename... T, typename Cmp>
struct merge<typelist<>, typelist<T...>, Cmp> {
    using type = typelist<T...>;
};
template <typename A, typename... As, typename B, 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...>, typelist<B, Bs...>, Cmp>::type>,
        concat_t<typelist<B>, typename merge<typelist<A, As...>, typelist<Bs...>, Cmp>::type>
        >::type
{ };
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<...>;
};
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));
}