In C++ I can chose between function pointers and function references (or even function values for the sake of completeness):
void call_function_pointer (void (*function)()) {
(*function) ();
}
void call_function_reference (void (&function)()) {
function ();
}
void call_function_value (void function()) {
function ();
}
When it comes to methods however, I don't seem to have this choice between pointers and references.
template <class T> void call_method_pointer (T* object, void (T::*method)()) {
(object->*method) ();
}
// the following code creates a compile error
template <class T> void call_method_reference (T& object, void (T::&method)()) {
object.method ();
}
This leads me to the assumption that method references do not exist in C++. Is that true? If it is, what is the reason they do not exist?
In the standard (e.g. N3337 - not the latest but fine for this) there is a note at the end of section 8.3.3.3 that reads:
[ Note: See also 5.3 and 5.5. The type “pointer to member” is distinct
from the type “pointer”, that is, a pointer to member is declared only
by the pointer to member declarator syntax, and never by the pointer
declarator syntax. There is no “reference-to-member” type in C++. —
end note ]
Also, of course, there are no "reference to member" type operators (which, hypothetically, the best I can come up with would be something like ->&
and .&
, although these are not consistent with dereferencing of data and function references, which require no special operator).
Why?
As for why; after a fun little historical investigation and failing to find any existing notes on it (I went all the way back to Cfront 2.0 where pointer-to-member was first supported -- edit: according to a far more credible document, the feature was actually first supported in Cfront 1.2), I asked the man himself and here is the reply:
Date: Sat, 22 Feb 2014 10:12:51 -0500
From: Bjarne Stroustrup <...>
Subject: Re: On lack of reference-to-member and CFront 2.0
On 2/22/2014 6:40 AM, Jason C wrote:
> My question is: C++ very clearly disallows the concept of
> "reference-to-member". Why is this? I have been doing a lot of
> research, and I traced the origin of "pointer-to-member" back (I
> think) to 1989 CFront 2.0. I read through the product reference manual
> and other documentation hoping to find an explanation of some sort but
> could not.
I don't really remember. It was 25+ years ago and the ARM is silent on
this. I added pointers to members to eliminate the need for a rare
breakage of the type system. I suspect that I didn't add references to
members because it did not seem worth the effort: there was no use case.
To be honest, I was expecting something far more arcane and complicated.
So there you have it: The next time somebody asks why there's no reference-to-member, you can confidently say, "Because there isn't!" (Note: See my ramblings in the comments; there is still some historical investigation to be done to get to 100% confidence.)
Personally, I've never once found a use for pointers-to-members in my own code, but a distinct rationale for their existence is given in Stroustrup's The Evolution of C++: 1985-1989, pp. 222-223.
By the way, your syntax for calling the hypothetical reference-to-member function:
object.method();
... does not make much sense, as there is no way to distinguish that syntactically from a call to an actual member named method()
.
hvd brings up a good point below: As you can see from the above, syntactically, there wouldn't really be a consistent way to dereference a reference-to-member. You have to distinguish it from normal member access, but at the same time you want to make it consistent with dereferencing of object and function references (which require no special operator), and I can't really think of anything that accomplishes both.