为什么 C++ 中不存在对成员的引用? [英] Why doesn't reference-to-member exist in C++?

查看:24
本文介绍了为什么 C++ 中不存在对成员的引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C++ 中,我可以在函数指针和函数引用之间进行选择(为了完整起见,甚至可以选择函数值):

void call_function_pointer (void (*function)()) {(*功能) ();}void call_function_reference (void (&function)()) {功能 ();}void call_function_value (void function()) {功能 ();}

然而,当谈到方法时,我似乎没有在指针和引用之间做出选择.

template void call_method_pointer (T* object, void (T::*method)()) {(object->*method) ();}//下面的代码会产生一个编译错误模板void call_method_reference (T& object, void (T::&method)()) {object.method();}

这让我假设 C++ 中不存在方法引用.真的吗?如果是,它们不存在的原因是什么?

解决方案

在标准中(例如 N3337 - 不是最新的,但很好)在第 8.3.3.3 节末尾有一条注释,内容如下:

<块引用>

[ 注意:另见 5.3 和 5.5.成员指针"类型是不同的从类型指针",即只声明指向成员的指针通过指向成员声明符语法的指针,而不是通过指针声明符语法.C++ 中没有成员引用"类型.—尾注]

当然,也没有对成员的引用"类型运算符(假设,我能想到的最好的方法是 ->&.&,尽管这些与不需要特殊运算符的数据和函数引用的解引用不一致).

为什么?

至于为什么;经过一个有趣的小历史调查并且没有找到任何现有的注释(我一路回到 Cfront 2.0 where pointer-to-member 首先被支持 -- 根据a更可信的文档,该功能实际上是在 Cfront 1.2 中首先支持的),我问了他本人,这是答复:

<前>日期:2014 年 2 月 22 日星期六 10:12:51 -0500来自:Bjarne Stroustrup <...>主题:Re:关于缺乏对会员和 CFront 2.0 的引用在 2/22/2014 6:40 AM,Jason C 写道:> 我的问题是:C++ 非常清楚地禁止了> 对成员的引用".为什么是这样?我做了很多> 研究,我追溯了指向成员"的起源(我> 认为)到 1989 CFront 2.0.我通读了产品参考手册> 和其他希望找到某种解释的文档,但是> 不能.我真的不记得了.这是 25 多年前的事了,ARM 对此保持沉默这.我添加了指向成员的指针以消除对罕见的需要类型系统的破坏.我怀疑我没有添加对成员,因为它似乎不值得付出努力:没有用例.

老实说,我期待更神秘和更复杂的东西.

所以你知道了:下次有人问为什么没有对成员的引用时,你可以自信地说,因为没有!"(注意:请参阅我在评论中的散文;为了达到 100% 的置信度,还有一些历史调查要做.)

就我个人而言,我从来没有在自己的代码中找到成员指针的用途,但是 Stroustrup 的C++ 的演变:1985-1989,第 222-223 页.

<小时>

顺便说一下,您调用假设的成员引用函数的语法:

object.method();

... 没有多大意义,因为无法在语法上将其与对名为 method() 的实际成员的调​​用区分开来.

hvd 在下面提出了一个很好的观点:从上面可以看出,从句法上讲,并没有真正一致的方法来取消引用对成员的引用.您必须将其与普通成员访问区分开来,但同时又希望使其与对象和函数引用的取消引用(不需要特殊运算符)保持一致,而且我真的想不出任何可以同时实现这两者的东西.

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.

这篇关于为什么 C++ 中不存在对成员的引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆