Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it necessary to pass iterator by const reference

Tags:

c++

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

like image 814
q0987 Avatar asked Jun 27 '13 02:06

q0987


People also ask

Can you pass an iterator reference?

Yes, passing by reference allows the function to change the parameter. That was the intent.

Can iterator be const?

An iterator can either be a constant or a non-constant/regular iterator.

Is it better to pass by reference or value?

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.

Is const pass by reference?

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 Answers

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).

like image 67
jogojapan Avatar answered Nov 10 '22 04:11

jogojapan