【问题标题】:Range-based for over pair list基于范围的过对列表
【发布时间】:2017-09-18 14:11:41
【问题描述】:

说,我想迭代一些内联定义的对。有没有更短的写法:

for(auto pair : std::initializer_list<std::pair<int,int>>{{1,2}, {3,4}})
    // ...

?

【问题讨论】:

  • 您可以为该类型设置别名:)
  • @StoryTeller 不会更短吧?
  • 循环表达式更短。如果您多次执行此循环,这将显着减少内容。
  • 不过,我不会。有效的方法是将其与 int list[][2] = {{1,2},{3,4}}; 放在外面,但我更喜欢内联解决方案 - 如果可用

标签: c++ c++11


【解决方案1】:

只需指定第一个元素是一对。其余的将自动推断:

for(auto& pair : {std::pair<int,int>{1,2}, {3,4}})
  ;

花括号括起来的初始化器被推导出为std::initalizer_list,并且第一个被命名为pair的元素将要求所有元素都是pair的初始化器。

您标记了 C++11,但为了完整起见,在 C++17 中它可以更短:

for(auto& pair : {std::pair{1,2}, {3,4}})
  ;

由于类模板参数推导。如果你没有,如果你想保持模板参数推导的好处,std::make_pair 会这样做:

for(auto& pair : {std::make_pair(1,2), {3,4}})
  ;

虽然表面上看,它在代码打高尔夫球方面不如 C++17 版本有用。

【讨论】:

  • 很好,谢谢 :) 根据您的回答,我还发现此版本适用于 C++17 以下:for(auto pair : {std::make_pair(1,2),{3,4},{5,6}})
  • @IceFire - 是的,它也适用于 C++11。然而,参数推导可以替换 C++17 中的make_pair
  • 是的,我最喜欢这个。不过,到目前为止,我的编译器不接受它。无论如何,我们似乎已经涵盖了所有选项
  • 您想通过引用而不是值来捕获对吗?在大多数平台上,两个整数和一个指针不应该都是 8 字节,但是整数是间接的一层吗?我想我希望在优化器运行后两者都生成相同的程序集......
  • @RyanP - 初始化列表内容无论如何都是不可变的,因此如果 OP 打算修改任何他们需要对副本进行操作的任何内容。如果他们不这样做,我觉得您担心的是过早优化。
【解决方案2】:

良好的 ol' 类型别名:

using pairlist = std::initializer_list<std::pair<int,int>>;

for(auto pair : pairlist{{1,2}, {3,4}})
{
    // stuff happens here
}

【讨论】:

  • 这个其实更长
  • @IceFire 平均不会超过一个循环。
  • 我对多重循环一无所知。事实上,想把这个列表内联清楚地表明我只有一个循环实例
  • @IceFire 然而,在这里提出这个问题,比源代码中任何可能的缩短产生了更多的输入。所以费心问这个问题是一个明确的指标,表明存在不止一个循环实例。
  • @IceFire 但是您的问题与未来的读者有关,他们的具体需求可能与您的不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多