Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.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++ - Fatal编程技术网

C++ 枚举元组上的类型的最佳方法?

C++ 枚举元组上的类型的最佳方法?,c++,C++,正如标题所说,我正在寻找枚举元组上类型的最佳方法。 因此,我的第一次尝试是下面的代码,这是对stackoverflow的另一个答案的改编,唯一的更改是包装在另一个类上,因此不需要将元组类型作为模板参数传递: 包括 使用名称空间std; 使用uInt=size\u t; 样板 类ECS_数据 { 私人: 元组数据; 私人: //类型索引 样板 结构内部类型索引; 样板 结构类型索引{ 静态constexpuint value=内部类型索引::value; }; 样板 结构内部类型索引{ 静态con

正如标题所说,我正在寻找枚举元组上类型的最佳方法。 因此,我的第一次尝试是下面的代码,这是对stackoverflow的另一个答案的改编,唯一的更改是包装在另一个类上,因此不需要将元组类型作为模板参数传递:

包括 使用名称空间std; 使用uInt=size\u t; 样板 类ECS_数据 { 私人: 元组数据; 私人: //类型索引 样板 结构内部类型索引; 样板 结构类型索引{ 静态constexpuint value=内部类型索引::value; }; 样板 结构内部类型索引{ 静态constexpuint value=1+内部类型索引::value; }; 样板 结构内部类型索引{ 静态constexpuint值=0; }; 公众: 样板 静态constexpuint Type_Index_v=Type_Index::value; }; int main { ECS_数据ECS_数据; 返回ecs_data.Type_Index_v;//返回4 } 问题是,对于一个有50种类型的元组,比如说,它实例化了1350个结构,每个结构都带有一个静态变量。 例如,对于元组: 用int调用将实例化1个结构内部类型索引,并停止,因为立即找到int。 用float调用将实例化2个结构的内部类型索引,然后内部类型索引,然后停止,因为找到了float,依此类推…导致3+2+1实例化,假设所有类型都调用了was类型索引。 所以N+N+N^2/2实例化,对吗?N类型索引和N+N^2/2内部类型索引部分专门化所有1350,其中包含一个静态变量

我的第二个解决方案是:

包括 包括 使用名称空间std; 使用uInt=size\u t; 样板 类ECS_数据 { 私人: 元组数据; 样板 内联静态uInt_索引=0; 公众: ECS_数据{ init_indexstd::make_index_序列; } 样板 uInt indexconst{return_index;} 私人: 样板 void init_indexstd::index_序列{…,_index=N;} }; int main { ECS_数据ECS_数据; 返回ecs_data.index; } 仍然以50种类型的元组为例,这次我们有: make_index_序列的2+N实例化 来自_索引的50个静态模板变量 索引中的50个成员函数实例化 从数字上看,这似乎更好,但现在是运行时,因为我看不到一种方法,可以在初始化时使用上述代码中的折叠表达式生成_indexconstexpr

所以我的问题是: 1您是否看到改进上述代码的方法? 2考虑到所有例如编译器优化魔法,最终哪个版本更好? 3您可以推荐一个更好的版本吗?
编辑:如果很难阅读,请原谅,stackoverflow上的文本编辑器完全忽略了我的新行。

我将只在3处尝试一下。我的照片看起来像这样:

样板 constexpr std::size\u t tuple\u index\u implstd::index\u序列{ //不要在这里使用std::disjunction\u v,因为它将返回bool constexpr std::size\u t idx=std::析取< //需要I+1以防止索引0上出现错误结果 标准::积分常数。。。, //失败案例 积分常数 >::价值; 静态_断言dx!=0,在元组中找不到类型; 返回idx-1; } 样板 constexpr std::size\u t tuple\u索引{ 返回元组索引 std::make_index_sequence{}; } 可以像这样使用

使用T=std::tuple;
//std::cout我只会在3点拍一张。我的照片看起来像这样:

样板 constexpr std::size\u t tuple\u index\u implstd::index\u序列{ //不要在这里使用std::disjunction\u v,因为它将返回bool constexpr std::size\u t idx=std::析取< //需要I+1以防止索引0上出现错误结果 标准::积分常数。。。, //失败案例 积分常数 >::价值; 静态_断言dx!=0,在元组中找不到类型; 返回idx-1; } 样板 constexpr std::size\u t tuple\u索引{ 返回元组索引 std::make_index_sequence{}; } 可以像这样使用

使用T=std::tuple; //std::cout我会做:

template <typename T, typename Tuple, std::size_t ... Is>
constexpr std::size_t tuple_index_impl(std::index_sequence<Is...>)
{
    // You might adapt here to handle duplicate differently
    return std::max({ std::is_same<T, std::tuple_element_t<Is, Tuple>>::value * (Is + 1)... });
}

template <typename T, typename Tuple>
constexpr std::size_t tuple_index()
{
   return tuple_index_impl<T, Tuple>(std::make_index_sequence<std::tuple_size<Tuple>::value>());
}
这两个方法的一个实例化是通过type+std::index_序列,编译器可以在一个唯一的实例化中神奇地完成

我会:

template <typename T, typename Tuple, std::size_t ... Is>
constexpr std::size_t tuple_index_impl(std::index_sequence<Is...>)
{
    // You might adapt here to handle duplicate differently
    return std::max({ std::is_same<T, std::tuple_element_t<Is, Tuple>>::value * (Is + 1)... });
}

template <typename T, typename Tuple>
constexpr std::size_t tuple_index()
{
   return tuple_index_impl<T, Tuple>(std::make_index_sequence<std::tuple_size<Tuple>::value>());
}

这两个方法的一个实例化是通过type+std::index_序列,编译器可以在一个唯一的实例化中神奇地完成

现在,请记住,所有这些复杂性将完全落在编译器的肩上,在编译时进行计算。没有实际的运行时开销。所以,只要你的编译器吞下了这个苦果,最终的结果应该是可以接受的。让它成为constexpr有什么问题?只要看看它,我就会说,让构造函数和init成员函数constexpr一切都能正常工作。你有错误吗?@n314
159是的,我确实犯了一个错误,但我不排除我不知道如何做正确,所以可能我犯了一个错误,所以这里的链接如果你想自己尝试->如果它有效,让我知道:嗯,是的,我看到了这个问题,我现在想不出解决的办法。@n314159从我所知道的情况来看,在编译时使用模板静态成员的方法是不可能的,除非有人愿意使用friend注入漏洞。现在,请记住,所有这些复杂性将完全落在编译器的肩上,在编译时进行计算。没有实际的运行时开销。所以,只要你的编译器吞下了这个苦果,最终的结果应该是可以接受的。让它成为constexpr有什么问题?只要看看它,我就会说,让构造函数和init成员函数constexpr一切都能正常工作。你有错误吗?@n314159是的,我有错误,但我不排除我不知道如何做正确,所以可能我犯了错误,所以这里的链接如果你想自己尝试->如果它有效,让我知道:嗯,是的,我看到了这个问题,我现在想不出解决的办法。@n314159从我所知道的情况来看,在编译时使用模板静态成员的方法是不可能的,除非有人愿意使用friend注入漏洞。