我很困惑函數指針參數的形式。以下兩種:函數指針作爲C++中的參數?
int fun(int (*g)())
{
cout << g() << endl;
}
int fun(int g())
{
cout << g() << endl;
}
這兩個定義都很好。但是,正如你已經注意到了,也有在這兩個函數原型一些差異:
- 第一個採用參數
int (*g)()
, - 而第二個需要參數
int g()
。
我的問題是他們之間有什麼區別?
我很困惑函數指針參數的形式。以下兩種:函數指針作爲C++中的參數?
int fun(int (*g)())
{
cout << g() << endl;
}
int fun(int g())
{
cout << g() << endl;
}
這兩個定義都很好。但是,正如你已經注意到了,也有在這兩個函數原型一些差異:
int (*g)()
,int g()
。我的問題是他們之間有什麼區別?
在第二種情況下,功能類型調整成爲指針到功能型,這使得這兩個功能是相同的。
int fun(int (*g)());
int fun(int g()); //same as above, after type adjustment
的C++ 03標準說,在§13.1/ 3,區別僅在於存在一個
參數的聲明是一個功能類型,另一種是一個指針,指向同一函數類型是等價物。 也就是說,函數類型被調整爲指向函數類型(8.3.5)的指針。
[Example:
void h(int());
void h(int (*)()); // redeclaration of h(int())
void h(int x()) { } // definition of h(int())
void h(int (*x)()) { } // ill-formed: redefinition of h(int())
]
這同樣與數組指針adjustement,與我們比較熟悉:
int fun(int *a);
int fun(int a[]); //same as above, after type adjustment
int fun(int a[10]); //same as above, after type adjustment
全部都是一樣的!
您可以通過我一個詳細的答案在這裏:
您實際上不能擁有函數類型的參數。函數參數聲明爲類型爲「返回T的函數」調整後的爲「指向函數返回T的指針」。因此,您的兩個定義實際上是相同的。(C具有相同的規則。)
類似的規則適用於陣列參數聲明例如此:
int main(int argc, char *argv[]);
實際上意味着此:
int main(int argc, char **argv);
大多數編譯器(例如MSVC,克++)接受所述第二形式作爲用於第一的簡寫。 Technicall你說你應該總是使用第一種形式。
他們接受它,因爲語言要求他們這樣做。請參見C++ 2003標準中的8.3.5p3([dcl.fct])。 –
@Keith在C標準中是否有等價的註釋? –
是,[C99](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf)6.7.5.3p7和p8。 –
你能解釋一下爲什麼C++將int g()衰減爲pointer-to-function-type,第一個是指向函數類型的指針,但第二個與第一個不同,正如你看到的那樣,符號。對於數組示例,它很容易理解。 – cheng
@Nawaz:這裏有兩個截然不同的規則。函數類型的表達式在大多數上下文中被隱式轉換爲函數指針(包括像'foo()')的普通函數調用;這種轉換通常被稱爲* decay *。聲明爲函數類型的參數被*調整成爲指針函數參數。這兩條規則是相關的,但原則上語言可以有一個規則,但不是另一個。同樣也適用於陣列到指針衰減和陣列到指針參數的調整。 –
@cheng:對於數組,爲什麼容易理解?因爲你更頻繁地看到這一點?另外,在這種情況下,C++標準允許指向函數類型轉換的函數類型。這就是它衰落的原因。 – Nawaz