Reputation: 2287
I am learning c++. I have learned referencing allow us to avoid copying. So I tried to get an iterator of a vector as reference to overwrite its elements.
// simplified function
std::vector<int>::iterator& GetIterator(std::vector<int>& vec) {
return vec.begin(); // compiler said that here is an error.
}
But compiler give me an error message and suggests to use const reference. I would not like to use const. Why cannot it get non-const reference? Or how to avoid copying of iterator? Thank you very much.
Upvotes: 0
Views: 292
Reputation: 3812
vec.begin();
return a temporary object and is r-value. You can't bind a l-value reference to a r-value. After returning from GetIterator
function, that temporary object will be destroyed and your reference will be dangled.
Return by value (std::vector<int>::iterator
) instead of reference. Iterator
s are designed to be copyable and cheap to copy. Also compilers use Return value optimization to avoid cost of coping objects.
Upvotes: 1
Reputation: 18964
You can sometimes use a reference to avoid a copy - but here you need a copy. The result of vec.begin()
is a temporary which ceases to exist when your function returns. If you want the value outside the function - and you do - then a copy is needed. (If you succeeded in forming a reference here it would be a "dangling reference", which is not a good thing.)
And in any case a lot of types are designed to be copied efficiently, and iterators are amongst those. And in fact the compiler can often avoid the copy for you, without you having to do any work at all - and this is one of those cases.
So the code without the reference is easier, correct, and already optimal.
Upvotes: 2
Reputation: 23774
correct code
std::vector<int>::iterator GetIterator(std::vector<int>& vec) {
return vec.begin(); // compiler said that here is an error.
}
your &
is extra.
The iterator is like int*
and gets a address.
And std::vector< type >::iterator
is like that.
So the vector.begin()
is like &int
so you can not bind it to iterator&
Upvotes: 0