2012-07-26 56 views
0

可能重複:
Why is it an error to use an empty set of brackets to call a constructor with no arguments?
Most vexing parse: why doesn't A a(()); work?刪除複製操作後的對象無效?

這一次讓我瘋了。也許它太簡單了。

struct Foo 
{ 
    Foo() {} 
    Foo(const Foo& f) {} 
    void work() {} 
}; 

int main() 
{ 
    Foo f(Foo()); 
    f.work(); 
} 

GCC 4.6給我:

error: request for member ‘work’ in ‘f’, which is of non-class type ‘Foo(Foo (*)())’ 

複製操作的有效代碼可能看起來像省音後:

int main() 
{ 
    Foo f; 
    f.work(); 
} 

但我爲什麼不能叫work()

編輯:

是的,重複(見下文)。首先搜索時沒有找到原始帖子,因爲這些症狀的來源位於我沒有想到的地方。

+1

爲什麼你首先寫'Foo f(Foo());',寫'Foo f;'有什麼問題,這應該按預期工作。您的第一個版本會創建一個完全不同的類型,如您在錯誤消息中所看到的。 – Nobody 2012-07-26 11:12:17

+0

它當然有點學術。來自研究什麼是構造函數被調用 – ritter 2012-07-26 11:13:05

回答

3

因爲Foo f(Foo());是一個函數聲明。

我想你想:Foo f;

或者如果要複製的構建:

Foo f((Foo())); 
+0

函數聲明不允許在基本塊內。它如何被解釋爲這樣? – ritter 2012-07-26 11:15:47

+0

@Frank:看看這裏:http://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-aa-work – Andrew 2012-07-26 11:16:35

+0

實際上你可以在函數裏面寫下這樣的東西:'int bar (int a,int b);'。它會編譯 – Andrew 2012-07-26 11:18:05

1

˚F實際上是主函數內的函數聲明。 嘗試

Foo f((Foo())); // to make the definition of f explicit enough. 
1

n3337 8.2

從函數式 演員和6.8中提到的也可以發生在一個聲明的上下文 聲明之間的相似性引起的歧義。在這種情況下,選擇範圍在函數 聲明與一個冗餘的括號參數 名稱和一個具有函數樣式類型的對象聲明作爲 初始值設定項。正如6.8中提到的含糊之處一樣, 決議是考慮任何可能是聲明聲明的構造。 [注意:一個聲明可以明確地由無效類型轉換消歧,用=表示 初始化或通過刪除圍繞着 參數名稱的冗餘括號。 - 注完] [實施例:

struct S { 
S(int); 
}; 
void foo(double a) { 
S w(int(a)); 
//function declaration 
S x(int()); 
//function declaration 
S y((int)a); 
//object declaration 
S z = int(a); 
//object declaration 
} 

- 端示例]

1

C++解析器解釋Foo f(Foo());表達式作爲函數聲明與簽名Foo(Foo(*)()),即返回的Foo的函數,並且採取指向返回Foo的函數的函數指針。圍繞像Foo f((Foo()));這樣的參數添加明確的括號將解決歧義。但考慮實際上只是在做Foo f;這可以避免冗餘代碼。

+0

函數聲明在基本塊中是不允許的。它如何被解釋爲這樣? – ritter 2012-07-26 11:19:12

+0

@Frank這是一個C遺產[鏈接](http://stackoverflow.com/questions/6089452/is-there-a-use-for-function-declarations-inside-functions) – 2012-07-26 11:23:08

+0

哦,太棒了!謝謝! – ritter 2012-07-26 11:24:28