首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用std::tie作为循环目标的范围

使用std::tie作为循环目标的范围
EN

Stack Overflow用户
提问于 2014-01-23 13:50:34
回答 2查看 8.4K关注 0票数 28

我想做一些类似以下的事情:

代码语言:javascript
复制
//std::vector<std::pair<TypeA, TypeB>> someInitializingFunction();
{
  TypeA a;
  TypeB b;

  for (std::tie(a, b) : someInitializingFunction()) {
    // do stuff;
  }
}

然而,这不是有效的代码,因为正如标准所说,基于for循环的范围被定义为等价于:

代码语言:javascript
复制
{
  auto && __range = range-init;
  for ( auto __begin = begin-expr,
      __end = end-expr;
      __begin != __end;
      ++__begin ) {
    for-range-declaration = *__begin;
    statement
  }
}

其中,for-range-声明定义为:

范围声明的

:属性说明符-序号{opt}decl-说明符-序号声明符

所以,阻碍我的是decl-specifier-seq没有被标记为可选?

因此,对于这个循环,我似乎必须退回到老式的循环:

代码语言:javascript
复制
std::vector<std::pair<TypeA, TypeB>> myList = someInitializingFunction();

{
  TypeA a;
  TypeB b;

  for (auto it = myList.begin(); it != myList.end(); ++it) {
    std::tie(a, b) = *it;
    // do stuff;
  }
}

但对于直观上看起来相当常见的任务,解包函数调用的结果,这在许多其他上下文中都是有效的,这在语法上似乎有点混乱。

有没有建议在语言中添加一些这样的东西?这是一个合理的想法吗?有没有更好的方法来做这个我忽略了的事情?我对标准的理解有误吗?

显然,我可以把我自己的函数组合在一起来做这件事,但是使用起来也有点麻烦。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-23 13:54:04

你仍然可以使用range-for!

代码语言:javascript
复制
//std::vector<std::pair<TypeA, TypeB>> someInitializingFunction();
{
  TypeA a;
  TypeB b;

  for (auto& p : someInitializingFunction()) {
    std::tie(a, b) = p;
    // do stuff;
  }
}

如果您不需要/不想修改p,则使用const auto& p

更新:使用上面的内容,您还可以使用std::move将元素移动到绑定的变量

代码语言:javascript
复制
for (auto& p : someInitializingFunction()) {
  std::tie(a, b) = std::move(p);
  // do stuff;
}

您提出的语法可能无法很好地处理它。一个人为的例子:

代码语言:javascript
复制
for (std::tie(a, b) : std::move(someInitializingFunction())) {}
// Note: std::move here is superfluous, as it's already an r-value
//    (may also hinder some optimizations). Purely for demonstration purposes.

这样,您就无法将元素的值移动到绑定的变量,因为r值容器中的begin()end()等不会产生移动迭代器。(是的,您可以将容器调整为返回移动迭代器,但这将是一个全新的故事)

票数 18
EN

Stack Overflow用户

发布于 2017-03-24 05:53:03

截至2017年3月21日,结构化绑定是C++的一部分。

这允许直接执行以下操作:

代码语言:javascript
复制
//std::vector<std::pair<TypeA, TypeB>> someInitializingFunction();
for (auto [a, b] : someInitializingFunction()) {
  // do stuff;
}
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21300410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档