c++ - 为什么 C++ 中不存在对成员的引用?

标签 c++ pointers reference pointer-to-member

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

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

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

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 ();
}

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

最佳答案

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

[ 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 ]

当然,也没有“对成员的引用”类型的运算符(假设我能想到的最好的应该是 ->&.& ,虽然这些与数据和函数引用的解引用不一致,它们不需要特殊的运算符)。

为什么?

至于为什么;经过有趣的小历史调查并且未能找到任何现有的注释(我一直回到 Cfront 2.0 其中 pointer-to-member was first supported -- 编辑:根据 a far more credible document ,该功能实际上是在 Cfront 1.2 中首次支持的),我问了这个人自己,这是回复:

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();

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

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

关于c++ - 为什么 C++ 中不存在对成员的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21952386/

相关文章:

php - 函数内部的静态变量不能保存对单例的引用

c++ - UDP套接字开始接收失败

c++ - std::string.append 的使用导致 "Stack around the variable ' 结果“已损坏”

python - pip install re2 报错

c - malloc时指针之间的区别

c - 可视化 printf 中指针指示的内容

javascript - 引用使 ExternalInterface.call 调用 javascript 函数的 html 对象

c++ - SDL 窗口在启动时关闭并返回 0

c - 从 char 指针检索最后一组输入值

c# - BinaryReader.Dispose(bool disposing) 创建流的本地引用。为什么?