簡體   English   中英

為什么Ampersand需要引用呼叫運營商

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM