39

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?

4

1 回答 1

49

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

[注:另见 5.3 和 5.5。“指向成员的指针”类型与“指针”类型不同,即指向成员的指针仅通过指向成员声明符的指针语法声明,而从不通过指针声明符语法声明。C++ 中没有“成员引用”类型。——尾注]

此外,当然,没有“对成员的引用”类型的运算符(假设我能想到的最好的东西是->&and .&,尽管这些与取消引用数据和函数引用不一致,这不需要特殊操作员)。

为什么?

至于为什么;经过一个有趣的历史调查并且未能找到任何现有的注释(我一直回到Cfront 2.0,其中首先支持指向成员的指针-编辑:根据更可信的文档,该功能实际上是首先在 Cfront 1.2 中支持),我问了这个人自己,这是回复:

日期:2014 年 2 月 22 日星期六 10:12:51 -0500
来自:Bjarne Stroustrup <...>
主题:回复:关于缺少对成员的引用和 CFront 2.0

2014 年 2 月 22 日上午 6:40,Jason C 写道:
> 我的问题是:C++ 非常明确地不允许
>“参考成员”。为什么是这样?我已经做了很多
> 研究,我追溯了“pointer-to-member”的起源(我
> 想想)到 1989 年的 CFront 2.0。我通读了产品参考手册
> 和其他文档希望找到某种解释,但
> 不能。

我真的不记得了。那是 25 多年前的事了,ARM 对此保持沉默
这个。我添加了指向成员的指针以消除对罕见的需要
类型系统的破坏。我怀疑我没有添加对
成员,因为它似乎不值得付出努力:没有用例。

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

所以你有它:下次有人问为什么没有提到成员时,你可以自信地说,“因为没有!” (注意:请参阅我在评论中的胡言乱语;仍然需要进行一些历史调查才能达到 100% 的置信度。)

就个人而言,我从来没有在我自己的代码中找到指向成员的指针的用途,但是在 Stroustrup 的The Evolution of C++: 1985-1989 , pp. 222-223 中给出了它们存在的独特理由。


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

object.method();

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

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

于 2014-02-22T10:05:03.437 回答