通过引用使用vector <int> :: iterator但有错误

时间:2017-07-24 06:11:47

标签: c++ c++11 vector iterator

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

int main()
{
    vector<int> vec = {1,2,3,4};
    for(auto & it = vec.begin(); it != vec.end(); ++it)
    {
        cout << *it << endl;
    }
}

大家好,在C ++中我通过引用使用iterator,例如“auto&amp; it”,编译器返回错误

  

“错误:无法初始化类型为'__gnu_cxx :: __ normal_iterator&gt;&amp;'的非const引用来自'std :: vector :: iterator {aka __gnu_cxx :: __ normal_iterator&gt;}'类型的右值        for(auto&amp; it = vec.begin(); it!= vec.end(); ++ it)   ”

我知道“auto it = vec.begin()”工作正常但是我们都知道通过引用传递将提高C ++的效率,那么为什么当我使用“auto&amp; it”时会出现这个错误?

3 个答案:

答案 0 :(得分:14)

  

所以当我使用&#34; auto&amp;它&#34 ;?

查看begin的返回类型。它不会返回引用。它按值返回迭代器。因此,返回值是右值类别中的临时值。 Temporaries(rvalues)不能绑定到非const左值引用。这就是错误&#34; 无效初始化类型的非const引用...来自类型的右值... &#34;装置

此外,修改容器的begin指针没有多大意义。 begin返回引用会很愚蠢。

解决方案:只需通过声明非引用值来创建迭代器的副本,就像您知道正常工作一样。

  

但众所周知,通过引用传递将提高C ++的效率

这是胡说八道。任意放置的参考不太可能提高效率。此外,你不是想在这里传递一个引用。您正在尝试绑定对函数返回的对象的引用。

几乎,如果不是总是,迭代器的复制速度非常快(std::vector::iterator当然是这样),并且你可能通过引用引入的间接可能效率较低。

答案 1 :(得分:4)

std::vector::begin返回一个右值(一个临时对象)。您不能使用auto&(非常量左值引用)引用临时对象。如果您希望通过引用获取上述返回值,则可以使用auto&&代替auto&,但我不建议使用。

使用auto&&会为std::vector::begin的返回值创建可变左值引用。这将是extend its lifetime,但我建议仅使用auto

使用右值引用不会提高代码的效率,compiler will optimize out通过值从std::vector::begin返回的interator对象的复制/移动。

答案 2 :(得分:0)

auto关键字从表达式获取类型作为临时对象(std :: vector :: begin) 因为它是临时对象,因此编译器无法推断它是引用它的。 汽车和放大器; (非常数左值)

在没有参考自动变量的情况下使用的最佳方法 auto&amp; var

如果您强制使用参考 C ++ 11引入了rvalue-reference,它可以绑定到临时对象更改为&amp;&amp;而不是&amp;如下

 vector<int> vec = {1,2,3,4};
    for(auto && it = vec.begin(); it != vec.end(); ++it)
    {
        cout << *it << endl;
    }