在C++中使用以 null 结尾的字符串实例化的 istringstream 对象的奇怪行为

Weird behavior of istringstream object instantiated with a null-terminated character string in C++

本文关键字:对象 istringstream 实例化 字符串 结尾 null C++      更新时间:2023-10-16

我有一个以 null 结尾的字符串存储在 char* 类型的s中。我想从s创建一个istringstream对象。由于 istringstream 的构造函数需要一个 string 类型的参数,我需要将schar* 转换为 string。为此,我通过以下方式使用其构造函数从s创建一个匿名string对象:

istringstream strin(string(s));

使用 gcc (4.7.3( 编译时,这似乎没问题。但是,在我添加了以下代码以使用strin

int r;
strin >> r;

我收到编译错误:

error: invalid operands of types 'std::istringstream(std::string*) {aka std::basic_istringstream<char>(std::basic_string<char>*)}' and 'int' to binary 'operator>>'

这对我来说似乎很奇怪,因为我不明白std::istringstream(std::string*)是什么类型。strin不应该是std::istringstream型吗?

我可以通过使用以下修改版本的代码之一来保持编译器满意。

解决方案 1:传递命名string对象

string str(s);
istringstream strin(str);

解决方案2:直接传递s,好像会隐式转换为string

istringstream strin(s);

解决方案 3:将s显式转换为string

istringstream strin((string)(s));

解决方案4:添加一对神奇的括号

istringstream strin((string(s)));

解决方案 5:告诉编译器s确实是char*类型

istringstream strin(string((char*)s));

除了原始的之外,所有这些都有效。谁能解释一下这里到底发生了什么?谢谢。

最令人烦恼的解析再次袭来:

std::istringstream strin( string( s ) );

声明一个函数(strin(,该函数将string作为参数,并返回一个std::istringstream。 (一个好的编译器可以在这里发出警告,因为你不可能实现这样的函数。 更正此问题的最简单方法是添加一些额外的括号:

std::stringstream strin( (string( s )) );

(实际上,这里最简单的解决方案是只写:

std::stringstream strin( s );

并让隐式转换完成这项工作。

这是

"最烦人的解析"问题。

istringstream strin(string(s));

这不是一个strin变量声明,而是一个函数的声明,它接受string,返回名为strin istringstream

您可以像这样修复这种情况。请注意那里的+。虽然s是标识符,但+s是表达式。

istringstream strin(string(+s));