gpt4 book ai didi

c++ - 处理元组内的右值引用

转载 作者:行者123 更新时间:2023-12-04 12:15:11 24 4
gpt4 key购买 nike

我想传递和转发包含右值引用的元组。但是我无法访问元组元素并以正确的方式进行转发。

在示例中,我还提供了一个带有命名元素的结构,而不是 std::tuple效果很好。

所以我根本找不到答案如何写那行:

return Y{ std::forward<decltype(std::get<0>(t))>( std::get<0>( t ) ) };

这样我就得到了正确的类型。

完整示例:
#include <iostream>
#include <tuple>

class X
{
private:
int data;
public:
X( int _data ): data{_data}{}
};


class Y
{
public:
Y( const X& ) { std::cout << "copy" << std::endl; }
Y( X&& ) { std::cout << "move" << std::endl; }
};

struct Sm { X&& x; };
struct Sc { X& x; };

template < typename AnyS >
Y func( const AnyS& s )
{
return Y{ std::forward<decltype(s.x)>(s.x) };
}

template < typename ... PARMS >
Y func( const std::tuple< PARMS... >& t )
{
return Y{ std::forward<decltype(std::get<0>(t))>( std::get<0>( t ) ) };
}

int main()
{
Sm sm{ X{1} };
Y ym = func( sm ); // should move, fine works

X x{1};
Sc sc{ x };
Y yc = func( sc ); // should copy, fine works

Y ytm = func( std::tuple< X& >{ x }); // should copy, works
Y ytc = func( std::tuple< X&& >{ X{1} }); // should move but copies! FAIL
}

我知道我可以使用元组本身的转发引用。这会正常工作,但在我的代码中是不可能的,因为我故意需要在其中包含一些数据重复,如果我通过右值引用转发元组本身,这将不起作用。如果我可以使用它,我可以使用 make_from_tuple .

最佳答案

std::get处理元组时返回对对象的引用。所以即使它是一个右值引用,返回类型 std::get将是一个左值引用。

要从元组中获取类型,请使用 std::tuple_element反而。

return Y{ std::forward<std::tuple_element_t<0, std::tuple<PARMS...>>>( std::get<0>( t ) ) };

编辑:
如果我理解你的评论是正确的,你应该能够通过别名元组类型来扩展它。
template <typename ... PARMS, std::size_t... Is>
Y func(const std::tuple<PARMS...>& t, std::index_sequence<Is...>)
{
using tt = std::tuple<PARMS...>;
return (Y{ std::forward<std::tuple_element_t<Is, tt>>( std::get<Is>( t ) ) }, ...);
}

template < typename ... PARMS, int... Is >
Y func( const std::tuple< PARMS... >& t )
{
return func(t, std::make_index_sequence<sizeof...(PARMS)>{});
}

关于c++ - 处理元组内的右值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58344110/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com