Home > Software design >  What is a difference between *iterator.fun() and (*iterator).fun()
What is a difference between *iterator.fun() and (*iterator).fun()

Time:10-24

I have simple code

#include <iostream>
#include <set>

using namespace std;
class Example
{
    string name;
public:
    Example(string name)
    {
        this -> name = name;
    }
    string getName() const {return name;}
};
bool operator<(Example a, Example b)
{
    return a.getName() < b.getName();
}
int main()
{
    set<Example> exp;
    Example first("first");
    Example second("second");
    exp.insert(first);
    exp.insert(second);
    for(set<Example>::iterator itr = exp.begin(); itr != exp.end();   itr)
    {
        //cout<<*itr.getName(); - Not working
        cout<<(*itr).getName()<<endl;
    }

}

I wonder why *itr.getName() doesn't work but (*itr).getName() works fine. What is the difference between *itr and (*itr) in this case?

CodePudding user response:

C has rules for operator precedence. According to these rules, the member access operator . has higher precedence than the dereference operator unary *.

Therefore, the expression

*itr.getName()

Is interpreted as though it had the parentheses:

*(itr.getName())

That is, it tries to evaluate itr.getName() and then dereference that. itr doesn't have any such member getName, so this doesn't compile. However, you can use the parentheses yourself to write:

(*itr).getName()

This dereferences itr first, and then accesses the getName member of the resulting Example. You can also use the dereference-and-member-access operator -> as follows:

itr->getName() // Same meaning as (*itr).getName()

CodePudding user response:

It's all about operator precedence.

The * (pointer/indirection) operator has a lower precedence than the . (member access) operator, therefore when doing *itr.getName(), the compiler will first try to access getName as a property of itr, and then attempt to dereference the value returned by getName(), which becomes the value of the expression.

In short, your first attempt is equivalent to:

auto name = iter.getName();
return *name;

Your second attempt works because of the brackets because (*itr) will first derefernce the pointer, then .getName() will call getName on whatever the pointer was pointing to. This all works because of the bracket.

However, C also has another operator called the arrow operator (->), which allows us to directly access a member property of a pointee. Therefore, you could also use:

auto name = iter->getName();
  • Related