我经常写一些片段
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)
问题是,也许以后我真的想要x并y指向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)
您可以使用函数自动化它,这样您就不必输入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)
| 归档时间: |
|
| 查看次数: |
2896 次 |
| 最近记录: |