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();