为什么不编译?

时间:2009-12-06 03:26:13

标签: c++ g++

当我尝试使用第一个表单声明iss时,g ++给了我“错误:不匹配'运算符>>'在'iss>> s'“中。但两个不同的声明不是一样的吗?

#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;
}

5 个答案:

答案 0 :(得分: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个参数的构造函数调用的临时函数时,你就会遇到这种情况,而快速解决方案是在其中一个参数周围放置额外的括号。

答案 1 :(得分:8)

这是因为istringstream对字符串采用const引用。所以你不能写这个:

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

嗯,实际上你可以,但这意味着你宣布一个函数iss,它需要std::string并返回std::istringstream。同样,你可以写:

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

这是非常恶心的C ++内容。

答案 2 :(得分:0)

我想有一些关于std :: string(char *)返回的类型的混淆,因为:

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

作品。

答案 3 :(得分:-1)

从字符串构造 istream 的第一个参数需要是: const string&amp; str 这不会创建:

    std::string(buf)

虽然以下代码说明了这一点,但它会泄漏内存,所以实际上并没有使用它。

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

答案 4 :(得分:-5)

您不需要使用namespace std;吗?