#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;
}
}
Hello all, in C++ I use iterator by reference such as "auto & it" and the compiler return the error
" error: invalid initialization of non-const reference of type '__gnu_cxx::__normal_iterator >&' from an rvalue of type 'std::vector::iterator {aka __gnu_cxx::__normal_iterator >}' for(auto & it = vec.begin(); it != vec.end(); ++it) ".
I know "auto it = vec.begin()" works fine but as we all know pass by reference will improve the efficiency in C++, so why this error occurs when I use "auto & it"?
so why this error occurs when I use "auto & it"?
See the return type of begin
. It does not return a reference. It returns the iterator by value. Therefore the return value is a temporary in the rvalue category. Temporaries (rvalues) can not be bound to non-const lvalue references. This is what the error "invalid initialization of non-const reference of type ... from an rvalue of type ..." means.
Besides, modifying the begin
pointer of the container would make little sense. It would have been silly for begin
to return a reference.
Solution: Just create a copy of the iterator by declaring a non-reference value, just like you know works fine.
but as we all know pass by reference will improve the efficiency in C++
This is nonsense. An arbitrarily placed reference is unlikely to improve efficiency. Besides, you aren't trying to pass a reference here. You are trying to bind a reference to an object returned by a function.
Almost, if not always, iterators are very fast to copy (std::vector::iterator
certainly is) and the indirection that you may potentially introduce with a reference may well be less efficient.
The std::vector::begin
returns an rvalue (a temporary object). You cannot take a reference to a temporary object with auto&
(non-const lvalue reference). If you wish to take the mentioned return value by reference, you can use auto&&
instead of auto&
but I don't recommend it.
Using auto&&
will create a mutable rvalue reference to the return value of std::vector::begin
. This will extend its lifetime but I recommend to use auto
only.
Using rvalue references won't improve the efficiency of your code, the compiler will optimize out the copy/move of interator object returned from std::vector::begin
by value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With