c++ 有没有一种方法可以将std::tuple移到结构体中?

gk7wooem  于 2023-06-07  发布在  其他
关注(0)|答案(1)|浏览(212)

假设我有一个struct和一个tuple,它们具有相同的字段:

struct foo {
  int x;
  std::string y;
  some_big_type z;
};

std::tuple<int, std::string> a{1, "hello", some_big_type{...}};

有没有一种方法可以使用移动构造一个foo对象?我的意思是,我不想为foo分配新的内存,而是构造一个foo,它充当已经分配的元组的“视图”。

dgiusagp

dgiusagp1#

c++20中,这只是std::make_from_tuple<foo>(a)
c++20之前,你必须编写自己的助手。

template<class T, std::size_t...Is, class Tuple>
T aggregate_from_tuple( std::index_sequence<Is...>, Tuple&& tuple ) {
  return { std::get<Is>( std::forward<Tuple>(tuple) )... };
}
template<class T, class Tuple>
T aggregate_from_tuple( Tuple&& tuple ) {
  auto indexes = std::make_index_sequence<
    std::tuple_size_v<std::decay_t<Tuple>>
  >{};
  return aggregate_from_tuple<T>(indexes, std::forward<Tuple>(tuple))
}

基本上是make_from_tuple,其中(){}替换。在c++20中,可以使用()初始化聚合。
C++的版本越老,上面的代码就越冗长。在c++11之前,我不确定我能做到这一点;上面的可能是c++17
这不会在元组中产生一个 view。它要么将其复制到foo,要么(如果使用std::move)将其移动到foo
通常,当复制昂贵时,移动类型是便宜的。
没有什么好方法来创建视图。但一个不好的方法是这样的:

struct foo_view {
  int& x;
  std::string& y;
  some_big_type& z;
};

不是你的foo类型这是一种对事物的非占有性的看法。
然后以同样的方式使用aggregate_from_tuple(或make_from_tuple),您将得到一个提供(接近零)成本重命名的对象。

相关问题