mora
mora

Reputation: 2287

Why cannot it get iterator as reference in c++?

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

Answers (3)

MRB
MRB

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. Iterators are designed to be copyable and cheap to copy. Also compilers use Return value optimization to avoid cost of coping objects.

Upvotes: 1

Alan Stokes
Alan Stokes

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

Shakiba Moshiri
Shakiba Moshiri

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

Related Questions