是否有任何很好的理由,一個空的圓括號(圓括號)無效在C++中調用默認的構造函數?默認構造函數與空括號
MyObject object; // ok - default ctor
MyObject object(blah); // ok
MyObject object(); // error
我似乎每次都會自動輸入「()」。這是不是有很好的理由?
是否有任何很好的理由,一個空的圓括號(圓括號)無效在C++中調用默認的構造函數?默認構造函數與空括號
MyObject object; // ok - default ctor
MyObject object(blah); // ok
MyObject object(); // error
我似乎每次都會自動輸入「()」。這是不是有很好的理由?
最棘手的解析
這與所謂的「C++的最棘手的解析」。基本上,任何可以被編譯器解釋爲聲明的東西都會被解釋爲聲明。
同樣的問題的另一實例:
std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());
v
被解釋爲的函數有兩個參數的聲明。
解決方法是添加另一對括號:
std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());
或者,如果你有C++ 11和列表初始化(也稱爲統一初始化)可供選擇:
std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};
有了這個,它不可能被解釋爲一個函數聲明。
我已經閱讀有效的STL,但我不記得看到這一點。我將不得不再次閱讀它,謝謝 – 2008-10-08 16:19:44
Nitpick:你可以在函數內聲明函數。它在C中被稱爲_local functions_,並且在C++中也至少允許`extern「C」foo();`-style。 – 2009-08-08 10:20:30
相同的語法用於函數聲明 - 例如,函數object
,不帶參數並返回MyObject
謝謝 - 我不會在其他代碼中聲明一個函數。但我認爲這是合法的。 – 2008-10-07 20:36:41
因爲編譯器認爲它是一個不帶參數並返回MyObject實例的函數的聲明。
因爲它是視爲聲明的函數:
int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
我其實更喜歡這個例外的答案,它是一個更清晰的問題是什麼原因 – thecoshman 2012-10-10 13:17:56
我想,編譯器會不知道這樣的說法:
myObject的對象();
是一個構造函數調用或函數原型聲明名爲對象返回類型爲爲MyObject並沒有參數的功能。
正如多次提到的那樣,這是一個聲明。這是爲了向後兼容。 C++的許多領域之一,因其遺留問題而變得愚蠢/不一致/痛苦/虛假。
您還可以使用結構的更詳細的方法:
MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);
在C++ 0x中,這也使得auto
:
auto object1 = MyObject();
auto object2 = MyObject(object1);
從n4296 [DCL。INIT]:
[注:
由於()
不是由語法初始化允許的,X a();
不是類X的對象的聲明,但 聲明一個功能的不帶參數並返回一個X. form()在某些其他初始化上下文中是允許的(5.3.4, 5.2.3,12.6.2)。
- 完注意事項]
正如其他人所說,這是一個函數聲明。由於C++ 11可以使用大括號初始化,如果您需要查看空的明確告訴您使用默認構造函數。
Jedi luke{}; //default constructor
有人應該想出一個更好的標題,但我想不出會是什麼。至少拼出「構造函數」來幫助搜索引擎。 – 2008-10-08 05:18:20
這是C++對上下文敏感的另一個很好的例子。如果`blah`是一個類,問題中的示例代碼也會失敗。 – Albert 2010-08-27 21:03:10