[英]Why Is Ampersand Necessary For Referencing The Call Operator
我認為C ++規范說在引用函數時不需要函數前面的符號,即
void bar();
void foo(void(*bar)());
foo(bar);
foo(&bar); // Same as above.
但是,我發現了一個並非如此的情況。 我試圖對lambda(僅一個參數)進行模板特化,這樣我就可以訪問lambda的return參數和輸入參數的類型。
// The ampersand in front of 'Fn::operator()' is necessary to make
// this code work.
template <typename Lambda>
struct Signature : public Signature<decltype(&Fn::operator())> {};
template <typename ClassT, typename RetT, typename ArgT>
struct Signature<RetT(ClassT::*)(ArgT) const> {
using ReturnType = RetT;
using ArgumentType = ArgT;
};
沒有&符號,clang抱怨道
error: call to non-static member function without an object argument
struct Signature : public Signature<decltype(Fn::operator())> {};
~~~~^~~~~~~~
我得到了代碼,但我想了解它的工作原理。 為什么這里的&符必要?
要獲取成員函數的地址,必須始終使用&
(和號)作為前綴。 這不僅適用於模板和/或lambdas,而且適用於C ++中的任何成員函數。
至於為什么 ,我們只能推測。 但這就是C ++一直以來的方式。 也許C兼容性是允許省略&
for for free功能的唯一原因。
函數的指針和成員函數的指針是不同的野獸。 當函數衰減到指向函數的指針時,對於成員函數或成員對象也是如此。 雖然指針轉換有一個標准函數,但成員函數或成員對象沒有類似的東西。 當你想獲得一個指向成員的指針時,你總是需要使用&
。
我不知道確切的推理,但我懷疑運營商的地址是必要的,以避免有時出現功能的錯誤,例如:
int f();
// ...
if (f) { // always true
}
雖然在不破壞C兼容性的情況下無法刪除從函數到函數指針的隱式轉換,但在引入成員和成員指針時沒有類似的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.