【问题标题】:Ranged based for loop for vector of booleans布尔向量的基于范围的 for 循环
【发布时间】:2020-05-03 14:02:11
【问题描述】:

std::vector<bool> 使用代理迭代器。

因此以下代码将无法编译(代码取自 related question 中接受的答案):

vector<bool> v = {true, false, false, true};
for (auto& x : v)
    x = !x;

在相关问题中,接受的答案指出要修改向量的组件,我们必须使用

for (auto&& x : v)
    x = !x;

但如果我只是这样做:

for (auto x : v)
    x = !x;

这会产生相同的结果。那么&amp;&amp; 不需要吗?

进一步为什么以下2个代码没有修改组件?

for (bool &&x : v)
    x = !x;

for (bool x : v)
    x = !x;

【问题讨论】:

  • 用第二个和第三个 sn-ps 检查 xtype,与最后两个相比,可能会很有启发性。
  • for 循环中放置一个断点,你会看到使用auto 不会导致x 具有bool 类型。
  • 各位,请阅读问题的第一行。
  • 我想我误解了代理迭代器的工作原理。这回答了我的最后一个问题。我仍然对为什么 auto &amp;&amp;auto 会产生相同的行为感到困惑?在我看到的所有相关问题中,答案使用auto &amp;&amp;
  • auto&& 的全部意义在于它对vector 和vector 都有效。你也不能使用 auto 并明确说明类型。

标签: c++ for-loop vector boolean


【解决方案1】:

TL;DR:代理对象知道如何读取和写入单个位,无论您如何保存它。将代理对象转换为 bool 会丢失该信息。


for (auto&& x : v)
    x = !x;

for (auto x : v)
    x = !x;

具有相同的行为,因为在每种情况下,通过取消引用 std::vector&lt;bool&gt;::iterator 获得的代理对象 (std::vector&lt;bool&gt;::reference) 都存储在 x 中。代理对象是按值存储还是按引用存储无关紧要——其修改代理位的行为是相同的。

for (bool &&x : v)
    x = !x;

for (bool x : v)
    x = !x;

代理对象被隐式转换为bool。这必然会丢失影响压缩位所需的信息(以及能力)。

请注意,这些都是实现定义的。您的实现也可以放弃空间优化,在这种情况下,您看到的行为可能会有所不同。只有auto&amp;&amp; 在每种情况下都有效。

【讨论】:

  • 我要补充一点,使用auto&amp;&amp; 而不是auto 的原因是它更通用。如果您将vector&lt;bool&gt; 替换为重物向量,auto 将进行复制,而auto&amp;&amp; 则不会。 (正如您所说,当前代码也是这种情况,但在性能方面并不重要)
  • @n314159 我没有添加它,因为我强烈建议不要将std::vector&lt;bool&gt; 和通用代码结合使用。嗯,在std::vector&lt;T&gt; 意义上是通用的。这只是一个巨大的雷区。
  • 我同意,不应该这样做(就我个人而言,如果可能的话,我会远离std::vector&lt;bool&gt;)。我只是觉得 OP 想知道,为什么在这种情况下几乎所有代码都使用 auto&amp;&amp; 而不是 auto。这就是为什么我觉得它有点相关。
猜你喜欢
  • 1970-01-01
  • 2016-10-31
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
相关资源
最近更新 更多