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

时间:2018-06-17 21:20:36

标签: c++ variadic-templates c++17 structured-bindings

简短版:

我希望能够将结构转换为元组。至少是这种类型。在下面的代码中, convertToTuple 函数不起作用,因为variadic参数不能用于结构化绑定(据我所知)。关键是: auto& [values ...] = value;

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 :: tuple和std :: pair,它确实有效,因为我可以从中提取类型:

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 个答案:

答案 0 :(得分:1)

您错过了为您提供程序员的结构化绑定的意义。它们是用来“解包”函数返回的多个参数的一种方式,从而可以轻松地处理各个参数。任何时候参数的数量都不是未知或可变的。

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

如上面的评论中所述,有一个Reflection TS正在开发中(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4746.pdf),但充其量只能提供一种工具来创建满足您需求的解决方案,而不是脱离常规。盒子解决方案。据我了解,Reflection TS涵盖了静态反射,您可以在其中推断类型的形状和内容,而不是动态反射,可以在其中动态创建类型。