是否有一个单行程序可以将元组/对解压缩到引用中?

新手上路,请多包涵

我经常写一些片段,比如

int x,y,z; tie(x,y,z) = g[19];

例如, g 之前声明过

vector<tuple<int,int,int>> g(100);

问题是,也许以后我真的想要 xy 指向 g 通过引用,重构是丑陋的,

 int &x = get<0>(g[19]);
int &y = get<1>(g[19]);
int &z = get<2>(g[19]);

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

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);

有没有更好的重构,更多的是 tie(..) 的赋值风格?

据我了解,困难在于引用坚持要 在声明时准确 初始化。所以,换句话说,有没有办法在 c++ 中使用 tie 语法进行多变量 _初始化_(这也会使早期的非引用用法更清晰)?

原文由 vujazzman 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 262
2 个回答

幸运的是,C++17 有一个解决这个问题的方法,即 结构化绑定声明。甚至非参考接口也可以改进。

 auto[x, y, z] = g[i];

上面的行声明了 x, y,z 并用 g[i] 的值初始化它们。它不仅更干净,而且对于构建成本高昂的类型可能更有效。

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

auto& [x, y, z] = g[i];

原文由 patatahooligan 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用函数将其自动化,这样您就不必输入 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 );
}

用法是:

 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 ) };

原文由 user2296177 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题