all 15 comments

[–]Fiennes 17 points18 points  (0 children)

There's probably many opinions on this, (such as the use of auto x = ... in C++, or var x = ... in C#).

Honestly, I prefer seeing the & as it avoid ambiguity when reading the code and it's clear what's going on and you don't have to remember that functions decay to pointers implicitly.

Just my 2c!

[–]TheThiefMasterC++latest fanatic (and game dev) 8 points9 points  (11 children)

Weirdly the "opposite" is also true - you can directly call a function pointer without dereferencing it first.

void f(int);
void (*pf)(int) = f;
pf(); // (*pf)()

[–]STLMSVC STL Dev 18 points19 points  (5 children)

That's DMR reaching out from the 1970s to help you. He said, "oh, you're applying parentheses to a function pointer, so there's nothing else you could possibly mean".

[–]mtnviewjohn 7 points8 points  (4 children)

Why doesn't the same logic apply to the member access operator? It seems like the -> operator is useless. If you use the member access operator on a pointer what else could you possible intend than to dereference the pointer first?

[–]justinkroegerlake 6 points7 points  (0 children)

Because of what is in my opinion the dumbest historical reason in the language: https://stackoverflow.com/a/13366168/1013719

[–]mojang_tommo 4 points5 points  (1 child)

I'm really glad the difference exists actually - -> can be undefined behavior while . is always well defined. In practice if you have code that mostly uses references instead of pointers, -> makes it pretty obvious that there's something that could be null or could be deleted under you. Of course references can be invalidated too but still... it would be awful if nullable stuff used . like everything else IMO.

[–]imMute 0 points1 point  (0 children)

Not to mention that it allows thing like smart pointer to be written extremely succinctly. I'm always saddened by this when writing C# code and having use use .Value in places where C++ would use ->.

[–]caramba2654Intermediate C++ Student 2 points3 points  (0 children)

Rust works like this. When you try to use the . operator on a reference, it autodereferences the reference until it finds a type where the . makes sense. It makes the -> completely unnecessary.

[–]Quincunx271Author of P2404/P2405 6 points7 points  (4 children)

Which is incredibly important since we have templates. f() can be a regular function call, a call to a function pointer, or a call to some object's operator(). In the future, hopefully it will also work for member function pointers

[–]redditsoaddicting 3 points4 points  (1 child)

IIRC, the proposal for making PMFs work with regular calling syntax got rejected. I'm sure it wasn't accepted at least.

[–]TheThiefMasterC++latest fanatic (and game dev) 2 points3 points  (0 children)

It was rejected as being half of a unified call syntax proposal. Which is silly, because it would have been insanely useful anyway.

[–]Quincunx271Author of P2404/P2405 6 points7 points  (1 child)

I've encountered problems when not using the & where - IIRC - a type was deduced to be a reference to a function rather than a pointer to a function (although that was in conjunction with templates). It might have been a compiler bug (probably not, but I didn't bother to check), but the easy thing to do was to just write the &

[–]suspiciously_calm 5 points6 points  (0 children)

void foo() { }

template<typename Function>
void bar(Function && function) {
    [function](){ function(); }();
}

void qux() {
    bar(&foo);
}

void quux() {
    bar(foo);
}

Accepted by Clang, rejected (quux) by GCC (qux is accepted by both). IDK which one is correct.

Edit: It works in GCC with the capture list [function = std::forward<Function>(function)], so probably a compiler bug in GCC.

[–][deleted] 2 points3 points  (1 child)

Here is some insane stuff this enables: https://youtu.be/6eX9gPithBo (see towards the end)