問題描述
在 C++ 中,我可以在函數(shù)指針和函數(shù)引用之間進行選擇(為了完整起見,甚至可以選擇函數(shù)值):
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) ();}//下面的代碼會產(chǎn)生一個編譯錯誤模板void call_method_reference (T& object, void (T::&method)()) {object.method();}
這讓我假設 C++ 中不存在方法引用.真的嗎?如果是,它們不存在的原因是什么?
在標準中(例如 N3337 - 不是最新的,但很好)在第 8.3.3.3 節(jié)末尾有一條注釋,內(nèi)容如下:
<塊引用>[ 注意:另見 5.3 和 5.5.成員指針"類型是不同的從類型指針",即只聲明指向成員的指針通過指向成員聲明符語法的指針,而不是通過指針聲明符語法.C++ 中沒有成員引用"類型.—尾注]
當然,也沒有對成員的引用"類型運算符(假設,我能想到的最好的方法是 ->&
和 .&
,盡管這些與不需要特殊運算符的數(shù)據(jù)和函數(shù)引用的解引用不一致).
為什么?
至于為什么;經(jīng)過一個有趣的小歷史調(diào)查并且沒有找到任何現(xiàn)有的注釋(我一路回到 Cfront 2.0 where pointer-to-member 首先被支持 -- 根據(jù)a更可信的文檔,該功能實際上是在 Cfront 1.2 中首先支持的),我問了他本人,這是答復:
老實說,我期待更神秘和更復雜的東西.
所以你知道了:下次有人問為什么沒有對成員的引用時,你可以自信地說,因為沒有!"(注意:請參閱我在評論中的散文;為了達到 100% 的置信度,還有一些歷史調(diào)查要做.)
就我個人而言,我從來沒有在自己的代碼中找到成員指針的用途,但是 Stroustrup 的C++ 的演變:1985-1989,第 222-223 頁.
<小時>順便說一下,您調(diào)用假設的成員引用函數(shù)的語法:
object.method();
... 沒有多大意義,因為無法在語法上將其與對名為 method()
的實際成員的調(diào)??用區(qū)分開來.
hvd 在下面提出了一個很好的觀點:從上面可以看出,從句法上講,并沒有真正一致的方法來取消引用對成員的引用.您必須將其與普通成員訪問區(qū)分開來,但同時又希望使其與對象和函數(shù)引用的取消引用(不需要特殊運算符)保持一致,而且我真的想不出任何可以同時實現(xiàn)這兩者的東西.
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++ 中不存在對成員的引用?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!