混沌 In C++::是類型?還是函數調用?

難度:

文前提醒:看這篇文章時須家長陪同並引導,以免走火入魔

 

先看看下面的代碼?   

struct A

{

     A(){}

};

 

template<typename T>

void func(T() )

{}

 

int main()

{

   A a( A() );    //(1), OK

   func( A() );   //(2), Wrong

   a = 5;          //(3), Wrong

}

 

(1) A  a( A() ); 是什麼意思?

在這裏是用A()創建一個對象,然後初始化對象a嗎?這裏真正的語a是一個參數爲返回A對象的無參函數指針的函數,所以它的真面目應該是A a( A (*)() ),其中的A()是個函數類型,在實際作參數時會退化爲一個A(*)()指針 。而這句僅僅起到聲明函數的作用。重點就在於A()並不是創建對象,而是一個無參的、返回爲A的函數類型

 

(2) func( A() ); 爲什麼會出錯呢?

這裏雖然函數模板func的參數同樣也是一個函數類型,那爲什麼會出錯呢? 其實在這裏A()就不是一個函數類型了,而是創建一個匿名對象。那麼這個函數即成了 void func( A ),而原本的函數模板func 類型是void ( T (*)() ),很明顯參數類型不匹配。

 

(3) a = 5; 現在應該沒有任何疑問了

int 傳遞給 A ()( A (*)() ),地球人都知道是錯的。

 

千萬別走火入魔!

是什麼導致了(1)(2)中的A()表現出不同的語義呢?

答:在這裏的 A() 就具有二義性:它即可以解釋爲新創建的類 A 的一個臨時對象(在此過程中要調用 A 的構造函數),也可以解釋爲一種函數類型聲明:其返回值爲A類型的對象,函數參數爲空。如果是前種解釋,則 a 爲類 A 的一個對象;如果是後一種,則整句就是一個函數聲明:聲明瞭一個函數 a,其返回值類型爲 A,函數參數(省略了參數名。對於函數聲明這樣做是可以的)是上述的一個函數類型。到底是前一種還是後一種解釋取決於它所在的語義環境。

 

更多

struct A

{

     A(int ){}

};

 

A a(A(1)); 在這裏A(1) 就不可能是“類型”了,因爲其中有個1,而A(1)就成了一個轉換函數調用形式,所以A(1)這裏是調用的A(int)

 

非常感謝whyglinux,爲本文指出錯誤並作出修改。

//The End

 

 

發佈了32 篇原創文章 · 獲贊 15 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章