class T
{
unordered_map<string, int> table;
...
void updateA(const unordered_map<string, int>::iterator& iter)
{
iter->second = 100;
}
void updateB(unordered_map<string, int>::iterator iter)
{
iter->second = 100;
}
};
Question> Which function is better(i.e. updateA or updateB)? If you have a better one, please propose.
Thank you
Yes, passing by reference allows the function to change the parameter. That was the intent.
An iterator can either be a constant or a non-constant/regular iterator.
Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.
When you pass by const reference, you take the argument in by reference (avoiding making any copies of it), but cannot make any changes to the original object (much as would happen when you would take the parameters in by value). There are subtle distinctions between all of them.
1) First, to answer the question in the title, is it necessary to pass iterators by (const) reference: No. An iterator acts as a proxy for the data item in the container, regardless of whether or not the iterator itself is a copy of or a reference to another iterator. Also in the case when the iterator gets invalidated by some operation performed on the container, whether you maintain it by copy or reference will not make a difference.
2) Second, which of the two options is better.
I'd pass the iterator by copy (i.e. your second option).
The rule of thumb is: Pass by reference if you either want to modify the original variable passed to the function, or if the object you pass is large and copying it involves a major effort.
Neither is the case here: Iterators are small, lightweight objects, and given that you suggested a const-reference, it is also clear that you don't want to make a modification to it that you want reflected in the variable passed to the function.
3) As a third option, I'd like you to consider adding const
to your second option:
void updateC(const unordered_map<string,int>::iterator iter)
{
iter->second = 100;
}
This ensures you won't accidentally re-assign iter
inside the function, but still allows you to modify the original container item referred to by iter
. It also may give the compiler the opportunity for certain optimizations (although in a simple situation like the one in your question, these optimizations might be applied anway).
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