我想知道是否有可能在
struct Foo
{
int x;
};
int main()
{
Foo foo;
auto [a0] = foo;
auto [a1, b1] = foo;
auto [a2, b2, c2] = foo;
// auto [a, b, c, ...] = foo;
}
只有第一个结构化绑定(bind)才有效,以便创建可采用任何Pod类型并返回包含所传递Pod的所有成员类型的元组的元函数。对于Foo它将返回std::tuple<int>
我尝试了类似的方法,但是没有成功:#include <tuple>
#include <type_traits>
#include <utility>
using namespace std;
template<typename T, typename U = void>
struct to_tuple;
template<typename T>
struct to_tuple<T, void_t<decltype([](T x) {
auto [a] = x;
return make_tuple(a);
}(declval<T>()))>>
{
using type = decltype([](T x) {
auto [a] = x;
return make_tuple(a);
}(declval<T>()));
};
template<typename T>
struct to_tuple<T, void_t<decltype([](T x) {
auto [a, b] = x;
return make_tuple(a, b);
}(declval<T>()))>>
{
using type = decltype([](T x) {
auto [a, b] = x;
return make_tuple(a, b);
}(declval<T>()));
};
template<typename T>
using to_tuple_t = typename to_tuple<T>::type;
struct Bar1
{
int x;
};
struct Bar2
{
int x;
float y;
};
int main()
{
static_assert(is_same_v<to_tuple_t<Bar1>, tuple<int>>);
static_assert(is_same_v<to_tuple_t<Bar2>, tuple<int, float>>);
}
最佳答案
这里的主要问题是结构化绑定(bind)声明就是-声明。我们无法形成“结构化绑定(bind)表达式”来获取类型,这是元编程中约束模板所必需的(例如void_t
模式或concept
/requires
子句)
对于[dcl.struct.bnd],尽管存在赋值表达式,但结构化绑定(bind)显然是声明。
模板元编程依赖于类型,而声明则没有类型。
例如,由于这个原因,您不能说decltype(int a = 10)
甚至decltype(int a)
。
您可以说decltype(int{})
,因为现在我们有了一个表达式。
因此,您的void_t
模式不起作用。
不幸的是,概念/约束对我们没有帮助,因为我们不能在require子句中使用声明(每个[gram.expr])
我个人认为,对于结构化绑定(bind),我们不能拥有相当于int{}
的功能,这有点疏忽。但是话又说回来,反光仍在进行中,所以这一点可能尚无定论。
编辑:作为dfri pointed out,有一个名为statement expressions的GNU扩展可以使之成为可能(作为扩展,它可以理解为不可移植的代码)
关于c++ - 使用结构化绑定(bind)的“反射(reflection)”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62692631/