為什麼這段 c++ 代碼需要加這對括弧才正確運行,是編譯器問題嗎?
正確運行的代碼:
std::ifstream fin("test.txt");
std::string str((std::istreambuf_iterator&(fin)), // 這裡多了一對括弧
std::istreambuf_iterator&());
cout &<&< str;錯誤代碼:
std::ifstream fin("test.txt");
std::string str(std::istreambuf_iterator&(fin), // 這裡少了括弧
std::istreambuf_iterator&());
cout &<&< str;第二段代碼的錯誤信息:
1&>源.obj : error LNK2019: 無法解析的外部符號 "class std::basic_string&,class std::allocator& &> __cdecl str(class std::istreambuf_iterator& &>,class std::istreambuf_iterator& &> (__cdecl*)(void))" (?str@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$istreambuf_iterator@DU?$char_traits@D@std@@@2@P6A?AV32@XZ@Z),該符號在函數 _main 中被引用1&>C:CodeC++C++ PrimerTestDebugTest.exe : fatal error LNK1120: 1 個無法解析的外部命令 前一段代碼可以輸出文件里的內容,但是後一段代碼出錯?
兩段代碼都沒語法錯誤吧,為什麼結果不一樣?
std::string str(std::istreambuf_iterator&
std::istreambuf_iterator&
相當於聲明了一個叫 str 的函數:
- 返回類型是 std::string
- 第一個參數叫 fin,類型是 std::istreambuf_iterator&
- 第二個參數沒有命名,類型是一個函數
- 返回類型是 std::istreambuf_iterator&
- 不接受參數
基本原則就是,有歧義的情況下,C++ 傾向於把能當聲明的東西都當聲明對待。
所以 C++11 引入了統一初始化語法:
std::string str{std::istreambuf_iterator&
std::istreambuf_iterator&
main.cpp:9:20: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
std::string str(std::istreambuf_iterator&
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:9:21: note: add a pair of parentheses to declare a variable
std::string str(std::istreambuf_iterator&
^
( )
main.cpp:11:18: warning: address of function "str" will always evaluate to "true" [-Wpointer-bool-conversion]
std::cout &<&< str;
~~ ^~~
main.cpp:11:18: note: prefix with the address-of operator to silence this warning
std::cout &<&< str;
^
2 warnings generated.
這是C++的一個設計缺陷:沒有給函數聲明提供一個專門的關鍵字,於是經常會混淆函數聲明與對象初始化。
我的治療方法通常是:把原地構建的臨時對象提出來,弄成一個變數。反正編譯器也會優化掉的。
Effective STL
Item 6: Be alert for C++』s most vexing parse.std::string str(std::istreambuf_iterator&
這種形式下,第一個參數意味一個名為fin的std::istreambuf_iterator&
講道理的話,參考這個:
http://www.cnblogs.com/yangyingchao/p/3394146.html
c++11 中直接用 {} 替代第二個參數就可以了,不用這麼麻煩了。
推薦閱讀:
TAG:C | MicrosoftVisualStudio | VisualC | 編譯器 |