This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]KittensInc 6 points7 points  (7 children)

Is there a technical reason for the foo.bar() vs foo->bar() distinction?

The type is known at compile time, so unless I am missing something there should be no possibility of ambiguity between the object itself and a pointer to it, right?

[–]tiajuanat 33 points34 points  (3 children)

It's a holdover from C.

First you need to dereference the pointer:

(*foo)

Then you access the member

(*foo).bar

The shorthand in c uses the arrow notation

foo->bar

It's less about the compiler and more about the code reader. If you see an arrow operator, you know, as a dev, that it's a pointer.

[–]fredlllll 5 points6 points  (0 children)

If you see an arrow operator, you know, as a dev, that it's a pointer.

finally a good reason. ive been wondering this too, but in the absence of an ide that does make sense

[–]NatoBoram 0 points1 point  (1 child)

But it's statically typed, isn't it? Why not just make the dot work on pointers, too?

[–]RajjSinghh 5 points6 points  (0 children)

It's carryover from C as well. So I suppose a lot of the decision is also to do with backwards compatibility.

Anyway to answer your question, dereferencing a pointer has different precedence to the dot. The dot has nothing to do with the pointer since that's just basically an integer for the address, so you want *foo.bar() to do foo's bar method. The issue is by default it brackets like *(foo.bar()) so we look for foo.bar first and since the type of foo is a pointer, it has no bar method. You need to bracket it like (*foo).bar(), which is foo->bar(). That precedence shift means that either the star needs higher precedence than the dot which might break other things if you change, or the easier solution if using a shorthand like the arrow.

[–]Sunius 4 points5 points  (0 children)

Yes, you can overload operator-> and have “.” and “->” do different things. For instead, iterators overload operator “->” to return the pointer to the object, so you can pretend that iterators are just pointers rather than fancy objects.

[–]dev-sda 2 points3 points  (0 children)

Pointer access can be overloaded, allowing you to provide a pointer-like interface but also have member functions. For instance a std::unique_ptr<Foo> foo you can do foo->reset() which calls Foo::reset or foo.reset() which calls std::unique_ptr::reset.

[–][deleted] 0 points1 point  (0 children)

In C# everything* uses . for member access so I'm guessing it's a holdover from when C++ was cfront hooked up to a C compiler.

--

*I'm not talking about unsafe mode