简体   繁体   English

迭代器和 &iterator 有什么区别?

[英]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

How are 'it' and '&it' different? 'it' 和 '&it' 有什么不同? How exactly are iterator and &iterator working? iterator 和 &iterator 究竟是如何工作的?

Case 1情况1

The auto keyword(without the use of & ) infers a non-reference type. auto关键字(不使用& )推断非引用类型。 This means in your case 1, auto infers it to be of type int .这意味着在您的情况 1 中, auto it推断为int类型。 This is a non-reference type, meaning that the values from the std::vector will get copied into the loop variable it , which in turn means that any changes made to it will not be reflected in the std::vector itself.这是一个非引用类型,这意味着来自std::vector的值将被复制到循环变量it中,这反过来意味着对其所做的任何更改it不会反映在std::vector本身中。

Case 2案例2

In case 2, however, due to the use of & in auto , the loop variable it is of type int& which is a reference type and any change you make on it will be reflected on the original vector.但是,在情况 2 中,由于在auto中使用了&it的循环变量是int&类型,这是一个引用类型,您对其所做的任何更改it将反映在原始向量上。

When using & for the type in a foreach loop, the loop will go over references to the items in the vector.在 foreach 循环中使用&作为类型时,循环将遍历对向量中项目的引用。

I might be more readable if you write the seconds loop as:如果您将秒循环编写为:

    for(auto& it : A){
        it = 0;
    }
    

And then it means that the element of type auto will be a reference to the element in A .然后这意味着auto类型的元素将是对A中元素的引用。

When not using & , each element is copied in each iteration, so when you assign to it, it has no effect on the original vector.不使用&时,每个元素都会在每次迭代中被复制,因此当您分配给它时,它对原始向量没有影响。

When you use auto in C++11 and later, the compiler has to deduce the type.在 C++11 及更高版本中使用auto时,编译器必须推断类型。
According to the documentation :根据文档

type is deduced using the rules for template argument deduction .使用模板参数推导的规则推导类型。

This means that qualifiers like const and volatile , as well as being a pointer or a refernce, are not a part of the deduced type.这意味着像constvolatile这样的限定符,以及作为指针或引用,不是推导类型的一部分。 In other words the deduced type will be the basic type of the expression assigned to the auto variable, without const , volatile or pointer/reference indirection.换句话说,推导的类型将是分配给auto变量的表达式的基本类型,没有constvolatile或指针/引用间接。

Example: If you have a function like:示例:如果您有如下功能:

A & GetA() { ... }

You can use it in several ways.您可以通过多种方式使用它。 In all of them auto will be deduced as A , but the type of a will be different:在所有这些中, 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.

Aplying this principle to your case:将此原则应用于您的案例:

  1. for(auto it : A) : for(auto it : A)
    auto will be deduced as int and this will be the type of it . auto将被推断为int ,这将是it的类型。 Therefore a copy will be made of the elements in A and placed into it .因此,将复制A中的元素并将其放入it No modification of the element copy will affect the original vector.元素副本的任何修改都不会影响原始向量。
  2. for(auto & it : A) : for(auto & it : A) :
    auto will still be deduced as int , but it will be of type int& . auto仍将被推断为int ,但it的类型为int& Therefore no copy will be made, rather we'll get a reference to the vector element.因此不会进行复制,而是我们将获得对向量元素的引用。 This is why the code was able to modify the vector.这就是代码能够修改向量的原因。

On a side note: using a range based loop (like you do), means that the variable of the loop will be assigned to the actual elements (or their refernce of course) in the collection.附带说明:使用基于范围的循环(就像您一样),意味着循环的变量将被分配给集合中的实际元素(或它们的引用)。 This is actually not an iterator, so using it as a variable name is misleadsing.这实际上不是一个迭代器,因此将it用作变量名会产生误导。 Better to use eg a in your case.最好在您的情况下使用例如a

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM