使用字符串临时构建istringstream

时间:2012-03-08 00:23:33

标签: c++ stl iostream

在尝试我的代码回答另一个问题时,我发现以下内容没有编译

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

using namespace std;

// (main omitted)
const char * coin = "3D";
istringstream ss(string(s));
int i;
ss >> hex >> i;              <--- error here
cout << (char) i << endl;

失败并出现以下错误:

test.cpp:15:11: error: invalid operands of types ‘std::istringstream(std::string) {aka std::basic_istringstream<char>(std::basic_string<char>)}’ and ‘std::ios_base&(std::ios_base&)’ to binary ‘operator>>’

以下编译并正确运行:

const char* coin = "3D";
string s(coin);
istringstream ss(s); // or directly istringstream ss("3D")
int i;
ss >> hex >> i;              
cout << (char) i << endl;

如果我查看istringstream的构造函数的定义,它接受const std::string&(实际上是basic_string<char>等价物),并且编译。所以我猜模板参数推导有一个我不理解的行为,并创建一个不那么符合istringstream,但为什么?

我正在使用GCC 4.6.1(Ubuntu风味)。

编辑:因为istringstream是一个typedef,我怀疑模板到底有什么问题。

1 个答案:

答案 0 :(得分:5)

istringstream ss(string(s));

您的编译器认为这是一个函数的声明,它使用string(名为s)并返回istringstream。将括号中的参数括起来以消除歧义。顺便问一下,s是什么?你的意思是coin吗?

istringstream ss( (string(coin)) );

如果您感到困惑,请阅读this

在这种特殊情况下,您当然可以这样做:

istringstream ss(coin);

如果你的编译器支持它,你也可以使用统一的初始化语法来避免MVP:

istringstream ss{string{coin}};

对大多数人来说这看起来有点奇怪,我知道这对我来说很奇怪,但那只是因为我已经习惯了旧的语法。