首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >结构化绑定和tie()

结构化绑定和tie()
EN

Stack Overflow用户
提问于 2018-03-30 12:28:53
回答 2查看 1.5K关注 0票数 10

鉴于这些声明:

代码语言:javascript
复制
int a[3] {10,20,30};
std::tuple<int,int,int> b {11,22,33};

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

代码语言:javascript
复制
auto [x1,y1,z1] = a;
auto [x2,y2,z2] = b;

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

代码语言:javascript
复制
std::tie(x1,y1,z1) = a;  // ERROR
std::tie(x2,y2,z2) = b;  // OK

这种方法适用于b,但不适用于a。是否有一个类似的简单构造可以用于a,还是必须分别提取a[0]a[1]a[2]

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-30 12:35:01

不是的。

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

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

代码语言:javascript
复制
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

或者,如果您知道有多少绑定(无论如何您必须这样做),您可以使用结构化绑定作为返回元组。但您必须同时指定大小,并为每个大小写写出一个大小写:

代码语言:javascript
复制
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
票数 10
EN

Stack Overflow用户

发布于 2018-03-30 19:48:09

只是为了好玩..。来模拟类似于

代码语言:javascript
复制
std::tie(x1,y1,z1) = a;

您可以编写一个包含指针数组的结构,并为相应的数组使用operator=()

代码语言:javascript
复制
template <typename T, std::size_t ... Is>
struct ptrArray<T, std::index_sequence<Is...>>
 {
   std::array<T*, sizeof...(Is)> ap;

   auto & operator= (T (&arr)[sizeof...(Is)])
    {
      ((*ap[Is] = arr[Is]), ...);

      return *this;
    }
 };

以及这个结构的功能。

代码语言:javascript
复制
template <typename T0, typename ... Ts>
ptrArray<T0, std::make_index_sequence<sizeof...(Ts)+1U>>
   makePtrArray (T0 & t0, Ts & ... ts)
 { return { { { &t0, &ts... } } }; }

代码语言:javascript
复制
makePtrArray(x1, y1, z1) = a;

很管用。

下面是一个完整的工作示例

代码语言:javascript
复制
#include <array>
#include <iostream>
#include <type_traits>

template <typename, typename>
struct ptrArray;

template <typename T, std::size_t ... Is>
struct ptrArray<T, std::index_sequence<Is...>>
 {
   std::array<T*, sizeof...(Is)> ap;

   auto & operator= (T (&arr)[sizeof...(Is)])
    {
      ((*ap[Is] = arr[Is]), ...);

      return *this;
    }
 };

template <typename T0, typename ... Ts>
ptrArray<T0, std::make_index_sequence<sizeof...(Ts)+1U>>
   makePtrArray (T0 & t0, Ts & ... ts)
 { return { { { &t0, &ts... } } }; }

int main ()
 {
   int x1, y1, z1;
   int a[3] {10,20,30};

   makePtrArray(x1, y1, z1) = a;

   std::cout << x1 << ' ' << y1 << ' ' << z1 << std::endl;
 }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49574460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档