[英]What is the difference between iterator and &iterator?
vector<int> A = {1, 2, 3};
//case 1
for(auto it : A){
it = 0;
}
print(A) //OUTPUT -> 1, 2, 3
//case 2
for(auto &it : A){
it = 0;
}
print(A) //OUTPUT -> 0, 0, 0
'it' 和 '&it' 有什么不同? iterator 和 &iterator 究竟是如何工作的?
auto
关键字(不使用&
)推断非引用类型。 这意味着在您的情况 1 中, auto
it
推断为int
类型。 这是一个非引用类型,这意味着来自std::vector
的值将被复制到循环变量it
中,这反过来意味着对其所做的任何更改it
不会反映在std::vector
本身中。
但是,在情况 2 中,由于在auto
中使用了&
, it
的循环变量是int&
类型,这是一个引用类型,您对其所做的任何更改it
将反映在原始向量上。
在 foreach 循环中使用&
作为类型时,循环将遍历对向量中项目的引用。
如果您将秒循环编写为:
for(auto& it : A){
it = 0;
}
然后这意味着auto
类型的元素将是对A
中元素的引用。
不使用&
时,每个元素都会在每次迭代中被复制,因此当您分配给它时,它对原始向量没有影响。
在 C++11 及更高版本中使用auto
时,编译器必须推断类型。
根据文档:
使用模板参数推导的规则推导类型。
这意味着像const
和volatile
这样的限定符,以及作为指针或引用,不是推导类型的一部分。 换句话说,推导的类型将是分配给auto
变量的表达式的基本类型,没有const
、 volatile
或指针/引用间接。
示例:如果您有如下功能:
A & GetA() { ... }
您可以通过多种方式使用它。 在所有这些中, auto
将被推断为A
,但a
的类型会有所不同:
auto a = GetA(); // The type of `a` will be `A`, and a copy will be made.
auto & a = GetA(); // The type of `a` will be `A&`. No copy will be made.
auto const & a = GetA(); // The type of `a` will be `A const&`. No copy will be made and the compiler will verify you do not modify the referenced object.
// etc.
将此原则应用于您的案例:
for(auto it : A)
:auto
将被推断为int
,这将是it
的类型。 因此,将复制A
中的元素并将其放入it
。 元素副本的任何修改都不会影响原始向量。for(auto & it : A)
:auto
仍将被推断为int
,但it
的类型为int&
。 因此不会进行复制,而是我们将获得对向量元素的引用。 这就是代码能够修改向量的原因。 附带说明:使用基于范围的循环(就像您一样),意味着循环的变量将被分配给集合中的实际元素(或它们的引用)。 这实际上不是一个迭代器,因此将it
用作变量名会产生误导。 最好在您的情况下使用例如a
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.