当前位置: 首页 > 知识库问答 >
问题:

未知自定义结构上的结构化绑定

盖和泰
2023-03-14

简短版本:

我希望能够将结构转换为元组。至少是那种类型。在下面的代码中,convertToTuple函数不起作用,因为可变参数不能用于结构化绑定(据我所知)。关键是:自动

struct Vec3 {
 float x;
 float y;
 float z;
};
template <typename T>
auto structToTuple(T &value) {
 auto& [values...] = value;  //doesn't work
 return std::make_tuple<decltype(values)...>(values...);
}
Vec3 v;
std::tuple<float, float, float> t = structToTuple(v);

基本上,我需要的是一种将自定义结构的类型转换为元组的方法,元组包含结构中的所有类型。例如:

struct Ray {Vec3, Vec3} -> std::tuple<
 std::tuple<float, float, float>,
 std::tuple<float, float, float>>;

具体问题:

我想创建一个模板函数,它将一个类型或一个类型列表作为模板参数,并生成一个纹理列表,每个纹理包含一个项目。另一个函数可以对纹理列表进行采样,并将值打包在一起以返回相同的类型。例如,如果我有一个类型:

std::pair<std::tuple<int, int>, int> value;
std::tuple<Texture<int, int>, Texture<int>> tex = createTexture(value);
std::pair<std::tuple<int, int>, int> thisshouldwork = sample(tex);

上面的代码只是一个简单的例子,说明我想做什么,而不是我的实际代码。在这种情况下,将创建2个纹理,一个纹理将包含元组中的两个int,另一个将包含单个int类型。我的意图是将纹理处理隐藏在接口后面,在那里我可以在纹理中存储任意值(只要它由一些简单类型组成),我可以将这些值上传到着色器的GPU。只要我只使用std::元组和std::对,它就可以工作,因为我可以从它们中提取类型:

template <typename... Args>
void f(std::tuple<Args...> t);

当模板参数是一个自定义结构时,我也希望能够这样做。例如:

struct Vec3 {
 float x;
 float y;
 float z;
};
Vec3 v;
Texture<float, float, float> tex = createTexture(v);

struct Ray{
 Vec3 pos;
 Vec3 dir;
};
Ray r;
std::tuple<Texture<float,float,float>, Texture<float,float,float>> tex2 = createTexture(r);

我甚至不相信这在当前的C标准中是可能的,但基于结构化绑定,这似乎是可能的。我的想法是这样的:

template <typename T>
auto structToTuple(T &value) {
 auto& [values...] = value;
 return std::make_tuple<decltype(values)...>(values...);
}
Vec3 v;
std::tuple<float, float, float> t = structToTuple(v);

就我而言,可变参数只是功函数或模板参数。但是如果structToTuple函数可以工作,那就解决了我的问题。

提前谢谢你们的帮助,伙计们!

更新:

我已经找到了解决问题的方法(不是通用的解决方案):https://github.com/Dwarfobserver/AggregatesToTuples/blob/master/single_include/aggregates_to_tuples.hpp

这个库的作者定义了一个结构到元组转换,但是它只在结构不超过50个参数的情况下才起作用。这解决了我在实践中的问题,尽管我仍然好奇它是否可以用任意的结构。

共有1个答案

孙嘉悦
2023-03-14

作为一名程序员,您没有理解结构化绑定的设计目的。它们是用来“解包”一个函数返回的多个参数的一种方式,可以方便地处理单个参数。任何时候都不存在未知或可变的参数数量。

https://en.cppreference.com/w/cpp/language/structured_binding

正如在上面的评论中所提到的,有一种反映正在进行中(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4746.pdf),但充其量,这将提供工具,为您的需求创建一个解决方案,而不是一个现成的解决方案。据我所知,反射TS涵盖静态反射,您可以推断类型的形状和内容,而不是动态反射,您可以动态创建类型。

 类似资料:
  • 结构体(structure,缩写成 struct)有 3 种类型,使用 struct 关键字来创建: 元组结构体,总的来说是根据元组来命名。 C 语言风格的结构体 c_struct。 单元结构体,不带字段,在泛型中很有用。 // 单元结构体 struct Nil; // 元组结构体 struct Pair(i32, f32); // 带有两个字段的结构体 struct Point { x:

  • 结构是用其他类型的元素建立的聚合数据类型。考虑下列结构定义: struct Time { int hour; // 0-23 int minute; // 0-59 int second; // 0-59 }; 结构定义用关键字 struct 引入。标识符 Time 是个结构标志(structure tag),命名结构定义并声明该结构类型(structure type)的变量。本例中,新类型名为

  • 假设我有一个类型为 是否可以像这样以嵌套的方式访问元素类型(即在Range for循环中使用时)

  • 在该示例中,标识符和之间的相应区别是什么?据我所知,结构绑定中的也有一个引用类型,但是为什么为它指明了一个非引用类型呢?

  • 在[dcl.struct.bind]9.6.4中,当初始值设定项是带有

  • 问题内容: 您如何初始化以下结构? 我试过了: 没用: 我试过了: 没用: 问题答案: 您是一个具有匿名结构类型的字段。因此,您必须重复类型定义: 但在大多数情况下,最好将其定义为rob74建议的单独类型。