我想知道是否有可能在

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/

10-11 23:21
查看更多