有没有一个单行将解包元组/对引用到引用中?

vuj*_*man 23 c++

我经常写一些片段

int x,y,z; tie(x,y,z) = g[19];
Run Code Online (Sandbox Code Playgroud)

例如,g早先宣布的地方

vector<tuple<int,int,int>> g(100);
Run Code Online (Sandbox Code Playgroud)

问题是,也许以后我真的想要xy指向g引用的内部,并且重构是丑陋的,例如

int &x = get<0>(g[19]);
int &y = get<1>(g[19]);
int &z = get<2>(g[19]);
Run Code Online (Sandbox Code Playgroud)

有时甚至更糟,例如,如果访问是一个更复杂的表达

tuple<int,int,int> &p = g[19]; // if the rhs was actually more complicated
int &x = get<0>(p);
int &y = get<1>(p);
int &z = get<2>(p);
Run Code Online (Sandbox Code Playgroud)

是否有更好的重构,更多的是分配的风格(...)?

我理解的困难在于参考文献坚持在他们的声明中完全初始化.所以,换句话说,有没有办法在c ++中使用类似tie语法进行多变量初始化(这也会使早期的非引用用法更清晰)?

pat*_*gan 11

幸运的是,C ++ 17正是针对此问题的解决方案,即结构化绑定声明。甚至可以改进非参考界面。

auto[x, y, z] = g[i];
Run Code Online (Sandbox Code Playgroud)

上一行声明x,y,z并使用的值对其进行初始化g[i]。它不仅更清洁,而且对于构造昂贵的类型可能更有效。

要获得对的成员的引用g[i],可以编写

auto& [x, y, z] = g[i];
Run Code Online (Sandbox Code Playgroud)


use*_*177 7

您可以使用函数自动化它,这样您就不必输入3行(或更多行):

template <class... Ts, std::size_t... Is, class Tuple>
decltype( auto ) tie_from_specified( std::index_sequence<Is...>, Tuple& tuple )
{
    return std::tuple<Ts...>{ std::get<Is>( tuple )... };
}

template <class... Ts, class Tuple>
decltype( auto ) tie_from( Tuple& tuple )
{
    return tie_from_specified<Ts...>( std::make_index_sequence<sizeof...( Ts )>{}, tuple );
}
Run Code Online (Sandbox Code Playgroud)

用法是:

int x{ 2 };
std::tuple<int, int&, int> g19( 1, x, 3 );

// new tuple: ref to get<0>( g19 ), value of get<1>( g19 ), ref to get<2>( g19 )
auto t0{ tie_from<int&, int, int&>( g19 ) };

// new tuple: ref to get<0>( g19 ), ref to get<2>( g19 )
auto t1{ tie_from_specified<int&, int&>( std::index_sequence<0, 2>{}, g19 ) };
Run Code Online (Sandbox Code Playgroud)