137

What is the arrow operator (->) a synonym for?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
P-A
  • 10,882
  • 8
  • 26
  • 19

7 Answers7

179

The following two expressions are equivalent:

a->b

(*a).b

(subject to operator overloading, as Konrad mentions, but that's unusual).

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 10
    Overloading issues are a lot less unusual than you think. Not long ago, STL implementors had no overloaded `->` operator for some iterator types so you *had* to use `*.`. Many libraries define them inconsistently. Becomes really annoying when you work with templates and don't know the precise type. – Konrad Rudolph Oct 21 '08 at 10:15
  • 1
    you can also do `a[0].b` instead of `(*a).b`. But it wouldn't be as properly structured. – Sellorio Jun 19 '13 at 03:35
  • 5
    Boy, after many years of c# programming, going back to c++ is not only cognitively taxing, the c++ syntax is just ugly and yucky. I feel like taking a shower after using it. Programs written in c and c++ just encourage bad programming. Apple, pre-unix, struggled to make the language as pretty as Pascal. – ATL_DEV Jul 09 '18 at 19:54
  • @ATL_DEV I'd argue that a lot of the ugly stuff isn't considered idiomatic anymore, but unfortunately that doesn't mean you can afford to not be familiar with it as a practicing C++ programmer. Also the syntactically nice path is often not the semantically nice path, but that also has been getting better not worse. But then again I have C++ Stockholm Syndrome. – Tim Seguine Aug 06 '18 at 09:13
  • 1
    @TimSeguine If you ever want to see pretty code, then look at the documentation for inside the Macintosh. I think they invented CamelCase. Very descriptive variable names and elegantly formatted code. They managed to make their later C code almost as gorgeous as their earlier Pascal code. – ATL_DEV Aug 07 '18 at 01:25
74

a->b is generally a synonym for (*a).b. The parenthesises here are necessary because of the binding strength of the operators * and .: *a.b wouldn't work because . binds stronger and is executed first. This is thus equivalent to *(a.b).

Beware of overloading, though: Since both -> and * can be overloaded, their meaning can differ drastically.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 2
    By `binding strength` you mean operator precedence? if not what is the difference between the two? – vishless Oct 10 '18 at 02:45
  • 2
    @Vizkrig Yes, the two terms are used interchangeably (although “operator precedence” seems to be much more frequent, at least in recent years). – Konrad Rudolph Oct 10 '18 at 08:16
47

The C++-language defines the arrow operator (->) as a synonym for dereferencing a pointer and then use the .-operator on that address.

For example:

If you have a an object, anObject, and a pointer, aPointer:

SomeClass anObject = new SomeClass();
SomeClass *aPointer = &anObject;

To be able to use one of the objects methods you dereference the pointer and do a method call on that address:

(*aPointer).method();

Which could be written with the arrow operator:

aPointer->method();

The main reason of the existents of the arrow operator is that it shortens the typing of a very common task and it also kind of easy to forgot the parentheses around the dereferencing of the pointer. If you forgot the parentheses the .-operator will bind stronger then *-operator and make our example execute as:

*(aPointer.method()); // Not our intention!

Some of the other answer have also mention both that C++ operators can be overload and that it is not that common.

MultiColourPixel
  • 1,222
  • 10
  • 19
P-A
  • 10,882
  • 8
  • 26
  • 19
  • 8
    `new SomeClass()` returns a pointer (`SomeClass *`), not the `SomeClass` object. And you start with declaring `anObject` and `aPointer` but you're using `p` afterwards. – musiphil Dec 07 '12 at 17:52
  • overall this explanation is theoretically very apt, only the change of objects makes it a little convoluted. But the process is better described – Code Man Oct 04 '15 at 22:47
19

In C++0x, the operator gets a second meaning, indicating the return type of a function or lambda expression

auto f() -> int; // "->" means "returns ..."
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 1
    Technically specking it is no longer an "operator" there, or is it? – Martin Ba Nov 06 '10 at 15:09
  • 6
    @Martin most people use the word "operator" for many things that aren't directly used for computing values. Like for "::" ("scope operator"). I don't know what the point of view of the standard is on this, exactly. In an abstract sense, one could view "->" as a functional operator mapping a sequence of types (parameters) to a return type, like the haskell operator, which is written "->" too. – Johannes Schaub - litb Nov 06 '10 at 15:15
  • 2
    @JohannesSchaub-litb: `::` is actually an operator, like `.` or `->`, and is called "scope resolution operator" in the standard. – musiphil Dec 07 '12 at 18:02
13

I mostly read it right-to-left and call "in"

foo->bar->baz = qux->croak

becomes:

"baz in bar in foo becomes croak in qux."

Lazer
  • 90,700
  • 113
  • 281
  • 364
Tetha
  • 4,826
  • 1
  • 16
  • 17
3

-> is used when accessing data which you've got a pointer to.

For example, you could create a pointer ptr to variable of type int intVar like this:

int* prt = &intVar;

You could then use a function, such as foo, on it only by dereferencing that pointer - to call the function on the variable which the pointer points to, rather than on the numeric value of the memory location of that variable:

(*ptr).foo();

Without the parentheses here, the compiler would understand this as *(ptr.foo()) due to operator precedence which isn't what we want.

This is actually just the same as typing

ptr->foo();

As the ->dereferences that pointer, and so calls the function foo() on the variable which the pointer is pointing to for us.

Similarly, we can use -> to access or set a member of a class:

myClass* ptr = &myClassMember;
ptr->myClassVar = 2; 
Tryb Ghost
  • 419
  • 1
  • 4
  • 14
0

You can use -> to define a function.

auto fun() -> int
{
return 100;
}

It's not a lambda. It's really a function. "->" indicates the return type of the function.

Zhang
  • 3,030
  • 2
  • 14
  • 31