假设我有一个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,它充当已经分配的元组的“视图”。
dgiusagp1#
在c++20中,这只是std::make_from_tuple<foo>(a)。在c++20之前,你必须编写自己的助手。
std::make_from_tuple<foo>(a)
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。通常,当复制昂贵时,移动类型是便宜的。没有什么好方法来创建视图。但一个不好的方法是这样的:
make_from_tuple
()
{}
foo
std::move
struct foo_view { int& x; std::string& y; some_big_type& z; };
不是你的foo类型这是一种对事物的非占有性的看法。然后以同样的方式使用aggregate_from_tuple(或make_from_tuple),您将得到一个提供(接近零)成本重命名的对象。
aggregate_from_tuple
1条答案
按热度按时间dgiusagp1#
在c++20中,这只是
std::make_from_tuple<foo>(a)
。在c++20之前,你必须编写自己的助手。
基本上是
make_from_tuple
,其中()
被{}
替换。在c++20中,可以使用()
初始化聚合。C++的版本越老,上面的代码就越冗长。在c++11之前,我不确定我能做到这一点;上面的可能是c++17。
这不会在元组中产生一个 view。它要么将其复制到
foo
,要么(如果使用std::move
)将其移动到foo
。通常,当复制昂贵时,移动类型是便宜的。
没有什么好方法来创建视图。但一个不好的方法是这样的:
不是你的
foo
类型这是一种对事物的非占有性的看法。然后以同样的方式使用
aggregate_from_tuple
(或make_from_tuple
),您将得到一个提供(接近零)成本重命名的对象。