2014-12-23 61 views
11

我遇到過這個C++問題:爲什麼「Foo f(Bar());」可以是一個函數的聲明,需要Bar類型並返回Foo類型?

問題:下面是一個定義還是聲明?

Foo f(Bar()); 

答:這可能是一個要麼是需要鍵入酒吧和回報Foo類型,或者是f定義爲一種Foo,它有一個構造函數型棒函數的聲明。問題是兩者的語法是相同的,所以爲了解決這個問題,C++標準規定編譯器必須首選函數聲明來對對象定義進行區分。

- 我不明白爲什麼它可以是「一個函數聲明需要類型Bar和返回類型Foo」?如何在參數列表中出現括號「()」?

+1

JFC不是這個東西再次 –

回答

11

函數f實際上將函數指針指向不帶參數的函數,並給出Barf的參數類型是Bar (*)()

此代碼不能編譯(我們可以看到在錯誤信息的實際的參數類型):

class Foo { }; 
class Bar { }; 

Foo f(Bar()); 

int main() { 
    Bar b; 
    f(b); 
    return 0; 
} 

但是這段代碼並編譯:

class Foo { }; 
class Bar { }; 

Foo f(Bar()); 

Bar g(); 

int main() { 
    f(g); 
    return 0; 
} 

第二意味着它可以像你在問題中所說的那樣,是你正在創建一個新的Foo對象,它叫做f,而你正在調用構造函數Bar()Bar的一個新實例)。這將是類似於:

Foo f = Foo(Bar()); 

在這種情況Foo f(Bar());雖然,第一種解釋是由編譯器選擇。

有點混亂的是,如果添加另一組括號,如

Foo f((Bar())); 

編譯器選擇第二個解釋。

+0

爲什麼第一段代碼不能編譯?是不是它在原始文章中提到的第二種可能性,f是一個Foo類型的定義,它具有一個類型爲Bar的構造函數? – athos

+0

@athos因爲'f'需要一個函數指針作爲第一個參數。在這種情況下,語句f(b);','b'不是func指針。 – greatwolf

+0

@greatwolf我明白了。該編譯器首選函數聲明來定義對象。 – athos

相關問題