2009-12-06 132 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));