2014-08-27 90 views
0

我注意到C++向量構造函數的一些奇怪行爲,任何人都可以爲我解釋嗎?謝謝。奇怪的C++向量構造函數的行爲

代碼段1作品:

#include <string> 
#include <vector> 
#include <iostream> 
#include <istream> 
#include <ostream> 
#include <iterator> 
#include <sstream> 
#include <algorithm> 

using namespace std; 

int main() 
{ 
    string str = "The quick brown fox"; 

    stringstream strstr(str); 

    istream_iterator<string> start(strstr); 
    vector<string> results(start, istream_iterator<string>()); 

    ostream_iterator<string> oit(cout, "\n"); 
    copy(results.begin(), results.end(), oit); 
} 

但代碼段2不:

#include <string> 
#include <vector> 
#include <iostream> 
#include <istream> 
#include <ostream> 
#include <iterator> 
#include <sstream> 
#include <algorithm> 

using namespace std; 

int main() 
{ 
    string str = "The quick brown fox"; 

    stringstream strstr(str); 

    vector<string> results(istream_iterator<string>(strstr), istream_iterator<string>()); 

    ostream_iterator<string> oit(cout, "\n"); 
    copy(results.begin(), results.end(), oit); 
} 

唯一的區別是在該載體的構造函數的第一參數。

+0

它是如何 「不工作」? – juanchopanza 2014-08-27 21:59:34

+2

最令人頭疼的解析罷工了。 – Beed 2014-08-27 22:05:14

+0

下面的答案在診斷中是正確的,但我只是建議一種替代解決方案,即IMO,這種解決方案更加易於理解。從矢量聲明你的迭代器在一個單獨的語句中。 'istream_iterator b(strstr),e;矢量結果(b,e);' – 2014-08-27 22:06:30

回答

5

Most vexing parse

vector<string> results(istream_iterator<string>(strstr), istream_iterator<string>()); 

被解析爲一個函數調用results返回vector,並採取命名istream_iterator<string>型和「不採取任何參數和返回istream_iterator<string>功能」類型的一個未命名的參數strstr一個參數。

將其更改爲:

vector<string> results = vector<string>(istream_iterator<string>(strstr), istream_iterator<string>()); 

或者你可以加括號,但它沒有多少可讀兩種:

vector<string> results((istream_iterator<string>(strstr)), istream_iterator<string>()); 

正如意見建議的BenjaminLindley,更可讀/無差錯少容易的方法是在單獨的語句來聲明迭代器:

auto begin = istream_iterator<string>(strstr); 
auto end = istream_iterator<string>(); 
vector<string> results(begin, end); 

注:

一些編譯器,如鐺,警告在此:

警告:括號中消除歧義,爲函數聲明[-Wvexing-解析]

+0

我也認爲「最令人頭疼的解析」就是答案。但是,我很困惑,我甚至不能編譯第二個例子。我一直認爲「最令人頭疼的解析」就像是一個noop?! – 2014-08-27 22:05:12

+0

@PhilippClaßen:不,聲明**不是**錯誤。然而,使用'結果'作爲一個向量是。 – quantdev 2014-08-27 22:06:31

+0

啊,你說得對。 :-) – 2014-08-27 22:07:35

0

的編譯器認爲此聲明

vector<string> results(istream_iterator<string>(strstr), istream_iterator<string>()); 

作爲函數聲明具有返回類型vector<string>和兩個參數,第一個類型爲istream_iterator<string>,第二個類型爲「返回類型爲istream_iterator<string>且沒有參數的函數」。改用要麼

vector<string> results((istream_iterator<string>(strstr)), istream_iterator<string>()); 

vector<string> results({ istream_iterator<string>(strstr), istream_iterator<string>() }); 

,這將是更清晰則說明符,可以用括號括起來。所以,你可以寫例如

int f(int (x), int (y)); 

或者

int (x) = 10; 
+0

@ T.C。感謝您的編輯。 – 2014-08-27 22:35:47