为什么C ++中不存在引用成员?

时间:2014-02-22 09:28:26

标签: 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 ++中不存在方法引用。真的吗?如果是,他们不存在的原因是什么?

1 个答案:

答案 0 :(得分:41)

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

  

[注:另见5.3和5.5。类型“指向成员的指针”是不同的   从“指针”类型,即仅声明指向成员的指针   通过指向成员声明符语法的指针,从不通过指针   声明符语法。 C ++中没有“reference-to-member”类型。 -   结束说明]

当然,也没有“成员”类型的操作符(假设我能想出的最好的类似于->&.&,尽管这些不是与解除引用数据和函数引用一致,不需要特殊操作符。)

为什么?

至于为什么;经过一个有趣的小历史调查,并没有找到任何现有的笔记(我一直回到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.

说实话,我期待更加神秘和复杂的事情。

所以你有它:下次当有人问为什么没有参考成员时,你可以自信地说,“因为没有!” (注意:在评论中查看我的随意内容;仍然需要进行一些历史性调查以获得100%的信心。)

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


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

object.method();

...没有多大意义,因为没有办法在语法上区别于对名为method()的实际成员的调​​用。

hvd在下面提出了一个很好的观点:从上面可以看出,从语法上来看,实际上并没有一种一致的方法来取消引用成员的引用。你必须将它与正常的成员访问区分开来,但同时你要使它与对象和函数引用的解除引用(它不需要特殊的操作符)一致,而我真的不能想到任何可以实现这两者的东西。 / p>