2009-12-06 172 views
4

當我嘗試使用第一種形式聲明iss時,g ++給我「錯誤:在'iss >> s'中不匹配'operator >>'。但是,這兩個不同的聲明不是做同樣的事情嗎?爲什麼不編譯?

#include <iostream> 
#include <sstream> 
#include <string> 


int main() { 
    const char *buf = "hello world"; 
    std::string ss(buf); 
    //std::istringstream iss(std::string(buf)); // this doesn't work 
    std::istringstream iss(ss); // but this does 
    std::string s; 
    iss >> s; 
} 

回答

11

這就是所謂的C++「最棘手的解析」:看起來像一個實例聲明你實際上看起來像一個函數聲明編譯器。

std::string name(); //function declaration 
std::string name; //object declaration with default constructor 

std::stringstream ss(std::string(buf)); //function declaration 
std::stringstream ss(std::string buf); //another function declaration 
std::stringstream ss(std::string); //also a function declaration 
std::stringstream ss(std::string()); //ditto, argument names are optional 

std::stringstream ss((std::string(buf))); //object declaration 

請注意最後一個例子中的額外括號。這些括號在函數聲明中不合法。

默認構造函數的第一個例子是衆所周知的。在第二種情況下增加了不起作用的是C++中參數名稱的括號是合法但可選的。例如,你可以這樣定義一個函數:

void foo(int (bar)) 
{} 

基本上你就當所有參數構造函數是從取0或1個參數的構造函數調用的臨時每次碰上這一點,並快速解決方案圍繞其中一個論點加上額外的括號。

-5

您是否需要使用namespace std;

+0

不,他在std命名空間中的前綴都是前綴。 – 2009-12-06 03:31:27

+0

好的,我很抱歉!如果我錯了,你不需要在島上投票,我犯了一個錯誤,每個人都這樣做。給一個人休息一下! – Jaba 2009-12-15 13:48:55

+3

這不是一個個人的仇恨 - 它只是一個指標,表明你的回答是錯誤的,這是投票的一部分。 – 2009-12-15 20:51:26

8

這是因爲istringstream接受一個字符串的const引用。所以,你不能只是寫:

std::istringstream iss(std::string(buf)); 

嗯,其實你可以,但它意味着你在聲明一個函數iss,這需要一個std::string並返回std::istringstream。等效地,你可以這樣寫:

std::istringstream iss(std::string buf); 

這是很不舒服的C++東西。

0

我想有有關的std :: string(字符*),因爲這返回的類型有些混亂:

std::istringstream iss((std::string)std::string(buf)); 

作品。

+0

這是因爲沒有強制轉換,它會聲明一個名爲'iss'的函數,它接受一個'std :: string'並返回一個'std :: istringstream'(參數名稱的括號是可選的)。由於一個強制轉換不能出現在聲明函數參數中,所以這必須清楚地*調用*接受'std :: string'('istringstream'的構造函數)的東西。 – UncleBens 2009-12-06 11:46:04

-1

從字符串構建istream的的第一個參數需要是:常量字符串& STR其中這不會產生:

std::string(buf) 

雖然下面的代碼說明了這一點,它泄漏內存,所以不要實際使用它。

std::istringstream iss(*new std::string(buf));