Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't reference-to-member exist in C++?

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?

like image 460
eyelash Avatar asked Feb 22 '14 09:02

eyelash


People also ask

Does reference exist in C?

No, it doesn't. It has pointers, but they're not quite the same thing. For more details about the differences between pointers and references, see this SO question.

How do you reference a class member in C++?

The members of a class are referenced (accessed) by using the object of the class followed by the dot (membership) operator and the name of the member. The members of a class are referenced (accessed) by using the object of the class followed by the dot (membership) operator and the name of the member.

Which function is not a member of class?

Explanation: Friend function is not a member of the class.


1 Answers

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.

like image 76
Jason C Avatar answered Sep 23 '22 04:09

Jason C