#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”时会出现这个错误?
答案 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;
}