为什么在这个例子中有"for(auto& x : v)"而不是"for(auto x : &v)"?
Why in this example there is "for(auto& x : v)" and not "for(auto x : &v)"?
我在Bjarne Stroustrup的The C++ programming language(4.版(中找到了这段代码。
在这个例子中,据我所知,我们递增x而不将v的值复制到x中。我的问题是,为什么我们引用x而不是v?
我试图通过分解并写在纸上来理解问题,简化内存中发生的事情,但我不明白。
void increment()
{
int v[]={0,1,2,3,4,5,6,7,8,9};
for(auto& x : v)
{
++x;
}
}
这是一个很好的初学者问题。看看 cppPreferred 在基于范围的 for 循环上有什么。由于v
是数组类型,因此上面的代码片段将扩展到
{
auto && __range = v;
for (auto __begin = __range, __end = (__range + bound);
__begin != __end; ++__begin)
{
auto& x = *__begin;
++x
}
}
其中"bound
是数组中元素的数量(如果数组大小未知或类型不完整,则程序格式不正确("[引用自上面的链接]。
我们可以看到,这种基于范围的 for 循环背后的机制确保我们在此处对v
执行左值引用:auto && __range = v
使用带有转发引用的类型推导,这做了正确的事情。
简而言之,在循环中auto& x
部分,您可以控制当指向范围的迭代器被取消引用时初始化的内容(*__begin
(。例如,使用auto& x
您可以获得对区域中元素的引用(您可以更改,影响范围(,使用const auto& x
,您将获得对区域中元素的const
限定引用(不能更改(。你可以用auto x
获得每个元素的副本,用const auto x
获得每个元素的const
限定副本,但后者几乎没有用处。
因为for
循环正在更改数组元素,所以您需要对每个元素的引用以递增它们。
如果您错误地拥有:
for(auto x : v)
{
++x;
}
v
中的任何内容都不会改变x
因为它是数组元素的副本。
制作它:
for(auto x : &v)
{
++x;
}
不编译,因为&v
是数组的地址(而不是数组中第一个元素的地址v
(,并且在范围表达式中无效。
但使用:
for(auto& x : v)
{
++x;
}
现在使x
引用v
中的元素,因此可以更改它们。
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 为什么当我为 for(auto& it : myUnorderedMap) {... = std::move(it.second)} 时,我会得到一个 const 引用?
- C++:带有 "auto" 的二维数组上的嵌套 For 循环
- 'for (auto c : str)' c到底是什么?
- 为什么在这个例子中有"for(auto& x : v)"而不是"for(auto x : &v)"?
- 请解释代码块"for(auto &it : iostr )"
- for (auto&a : a) 在语法上是正确的吗?
- 为什么基于范围的 for 语句通过 auto&& 获取范围?
- 有什么理由不使用 auto& 进行C++基于范围的 for 循环?
- for(auto&x:unordered_map变量) - 此语句抛出错误
- "for (auto&e : a)"比"for (auto&e : a)"更有效吗?
- 在基于嵌套范围的 for 循环中使用 auto(用于迭代)
- 在 for-each 循环中使用 'auto' 时是否需要添加'const'?
- 强制auto为range for循环中的引用类型
- 使用"for(auto&e : cont)"安全吗?矢量有什么问题<bool>?
- auto在基于范围的for循环中是可选关键字吗?
- 在 S 被解析为 for(auto &s :text)后,S 应该是什么类类型?
- 澄清使用for(auto iter: value)遍历映射
- 我们是否应该始终使用 auto&&&for 局部变量
- 是否可以替换(自动 i=0;i<n;i++) ... with for(auto i:<something>) 而不使用向量?