结构化绑定和领带()

oz1*_*1cz 10 c++ c++17 structured-bindings

鉴于这些声明:

int a[3] {10,20,30};
std::tuple<int,int,int> b {11,22,33};
Run Code Online (Sandbox Code Playgroud)

我可以使用结构化绑定声明来解码ab:

auto [x1,y1,z1] = a;
auto [x2,y2,z2] = b;
Run Code Online (Sandbox Code Playgroud)

但是,如果x1,y1等已经存在了,我该怎么办?

std::tie(x1,y1,z1) = a;  // ERROR
std::tie(x2,y2,z2) = b;  // OK
Run Code Online (Sandbox Code Playgroud)

这适用b但不适用a.是否有一个类似的简单构造,对工作a,还是我去取a[0],a[1]a[2]分别?

Bar*_*rry 10

不.

结构化绑定具有特定的语言规则来处理数组和某些其他类型.tie()具体是a tuple<T&...>,只能从另一个分配tuple<U&...>.


使用数组的情况,您可以编写一个函数将该数组转换为引用元组:

template <typename T, size_t N, size_t... Is>
auto as_tuple_impl(T (&arr)[N], std::index_sequence<Is...>) {
    return std::forward_as_tuple(arr[Is]...);
}

template <typename T, size_t N>
auto as_tuple(T (&arr)[N]) {
    return as_tuple_impl(arr, std::make_index_sequence<N>{});
}

std::tie(x1, y1, z1) = as_tuple(a); // ok
Run Code Online (Sandbox Code Playgroud)

或者,如果您知道有多少绑定(无论如何),您可以使用结构化绑定作为回馈元组.但是你必须指定大小并为每个大小写出一个案例:

template <size_t I, typename T>
auto as_tuple(T&& tuple) {
    if constexpr (I == 1) {
        auto&& [a] = std::forward<T>(tuple);
        return std::forward_as_tuple(a);
    } else if constexpr (I == 2) {
        auto&& [a, b] = std::forward<T>(tuple);
        return std::forward_as_tuple(a, b);
    } else if constexpr (I == 3) {
        // etc.
    }
}

std::tie(x1, y1, z1) = as_tuple<3>(a); // ok
Run Code Online (Sandbox Code Playgroud)

  • @PasserBy`get`对于`std :: array`不是SFINAE友好的,它没有为原始数组定义(对吗?),它肯定不适用于具有全公共成员的类型. (2认同)