Reputation: 8421
While trying my code to answer another question I found out that the following didn't compile
#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;
It failed with the following error:
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>>’
While the following compiled and ran properly :
const char* coin = "3D";
string s(coin);
istringstream ss(s); // or directly istringstream ss("3D")
int i;
ss >> hex >> i;
cout << (char) i << endl;
If I look at the definition of the constructor of istringstream
, it accepts const std::string&
(actually the basic_string<char>
equivalent), and that compiles. So I guess the template argument deduction has a behaviour I don't understand and create a not so conform istringstream
, but why ?
I am using GCC 4.6.1 (Ubuntu flavor).
EDIT : since istringstream is a typedef, I doubt there's any problem with templates in the end.
Upvotes: 2
Views: 1985
Reputation: 103693
istringstream ss(string(s));
Your compiler thinks that's a declaration of a function taking a string
(named s
) and returning an istringstream
. Surround the argument in parentheses in order to disambiguate it. By the way, what is s
? Did you mean coin
there?
istringstream ss( (string(coin)) );
Read this if you are confused.
In this particular case, you could of course have just done this:
istringstream ss(coin);
If your compiler supports it, you can also avoid the MVP using uniform initialization syntax:
istringstream ss{string{coin}};
That probably looks a bit odd to most people, I know it looks odd to me, but that's just because I'm so used to the old syntax.
Upvotes: 5