为什么不编译?

Ste*_*ven 4 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;
}
Run Code Online (Sandbox Code Playgroud)

Unc*_*ens 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
Run Code Online (Sandbox Code Playgroud)

请注意上一个示例中的额外括号.这些括号在函数声明中不合法.

使用默认构造函数的第一个示例是众所周知的.在第二种情况下增加不明确性的是C++中参数名称的括号是合法的但是可选的.例如,您可以定义如下函数:

void foo(int (bar))
{}
Run Code Online (Sandbox Code Playgroud)

基本上,每当构造函数的所有参数都是来自带有0或1个参数的构造函数调用的临时函数时,你就会遇到这种情况,而快速解决方案是在其中一个参数周围放置额外的括号.


Fra*_*ank 8

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

std::istringstream iss(std::string(buf));
Run Code Online (Sandbox Code Playgroud)

嗯,实际上你可以,但这意味着你正在声明一个函数iss,它需要一个std::string并返回std::istringstream.同样,你可以写:

std::istringstream iss(std::string buf);
Run Code Online (Sandbox Code Playgroud)

这是非常恶心的C++东西.