【问题标题】:What is different between two codes of for loop?两个for循环代码有什么不同?
【发布时间】:2021-02-18 06:34:42
【问题描述】:
#include <vector>
#include <iostream>
using namespace std;

int main(void)
{
    vector<int> a = {1, 2, 3, 4, 5};
    for (auto &x : a)
        cout << x << endl;
}
#include <vector>
#include <iostream>
using namespace std;

int main(void)
{
    vector<int> a = {1, 2, 3, 4, 5};
    for (auto x : a)
        cout << x << endl;
}

上面的两个代码打印相同的值(1、2、3、4、5)。 但是初始化 &x 和 x 之间有什么不同吗? 感谢阅读!

【问题讨论】:

  • 第一个是引用,另一个是值。在第一个示例中,您可以更改 ax 的元素。

标签: c++ reference auto range-based-loop


【解决方案1】:

您编写的代码的输出没有区别。但是,如果您尝试在循环中更改 x 的值,则会有不同。

#include <vector>
#include <iostream>
using namespace std;

int main(void)
{
    vector<int> a = {1, 2, 3, 4, 5};
    for (auto x : a)
        x = 0;
    for (auto x : a)
        cout << x << endl;
}

非常不同:

#include <vector>
#include <iostream>
using namespace std;

int main(void)
{
    vector<int> a = {1, 2, 3, 4, 5};
    for (auto & x : a)
        x = 0;

    for (auto x : a)
        cout << x << endl;
}

在第二个中,向量a 在程序结束时将全为零。这是因为auto 本身会将每个元素复制到循环内的临时值,而auto &amp;reference 用于向量的元素,这意味着如果您将某些内容分配给引用它会覆盖引用指向的任何位置。

【讨论】:

  • 谢谢!你的回答真的很有用。
  • 如果数据类型不是简单的 int,而是一些大类,则另一个区别变得可见。然后制作副本可能会非常昂贵(== 慢),而仅获取参考总是很快。
  • @U.W.一个很好的例子来证明它(也许)godbolt.org/z/xnnf9Y 将 'auto' 替换为 'auto &' 并且副本消失了。但是现在我已经手动添加了复制构造函数,这会改变编译器允许进行的优化吗?如果只调用 const 方法,也许允许一个简单的可复制对象优化副本?如何测试?
  • 或者不修改类构造函数的更好的证明。 godbolt.org/z/qP6bWa查看临时地址。
  • @bradgonesurfing 如何测试?好吧,只编译到汇编级别并查看代码。就这么简单! :-)
猜你喜欢
  • 1970-01-01
  • 2011-08-16
  • 2022-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多