繁体   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

'it' 和 '&it' 有什么不同? iterator 和 &iterator 究竟是如何工作的?

情况1

auto关键字(不使用& )推断非引用类型。 这意味着在您的情况 1 中, auto it推断为int类型。 这是一个非引用类型,这意味着来自std::vector的值将被复制到循环变量it中,这反过来意味着对其所做的任何更改it不会反映在std::vector本身中。

案例2

但是,在情况 2 中,由于在auto中使用了&it的循环变量是int&类型,这是一个引用类型,您对其所做的任何更改it将反映在原始向量上。

在 foreach 循环中使用&作为类型时,循环将遍历对向量中项目的引用。

如果您将秒循环编写为:

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

然后这意味着auto类型的元素将是对A中元素的引用。

不使用&时,每个元素都会在每次迭代中被复制,因此当您分配给它时,它对原始向量没有影响。

在 C++11 及更高版本中使用auto时,编译器必须推断类型。
根据文档

使用模板参数推导的规则推导类型。

这意味着像constvolatile这样的限定符,以及作为指针或引用,不是推导类型的一部分。 换句话说,推导的类型将是分配给auto变量的表达式的基本类型,没有constvolatile或指针/引用间接。

示例:如果您有如下功能:

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.

将此原则应用于您的案例:

  1. for(auto it : A)
    auto将被推断为int ,这将是it的类型。 因此,将复制A中的元素并将其放入it 元素副本的任何修改都不会影响原始向量。
  2. for(auto & it : A) :
    auto仍将被推断为int ,但it的类型为int& 因此不会进行复制,而是我们将获得对向量元素的引用。 这就是代码能够修改向量的原因。

附带说明:使用基于范围的循环(就像您一样),意味着循环的变量将被分配给集合中的实际元素(或它们的引用)。 这实际上不是一个迭代器,因此将it用作变量名会产生误导。 最好在您的情况下使用例如a

暂无
暂无

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

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