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

StackOverflow https://stackoverflow.com/questions/18182481

  •  24-06-2022
  •  | 
  •  

Question

I have a null-terminated character string stored in s of type char*. I want to create an istringstream object from s. Since the constructor of istringstream expects a parameter of type string, I need to convert s from char* to string. I did this by creating an anonymous string object from s using its constructor in the following way:

istringstream strin(string(s));

This seems OK when compiled using gcc (4.7.3). However, after I added the following codes to use strin

int r;
strin >> r;

I got the compile error:

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

This seems weird to me since I don't understand what the type std::istringstream(std::string*) is. Shouldn't strin be of type std::istringstream?

I can keep the compiler happy by using one of the following modified versions of the code.

Solution 1: pass a named string object

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

Solution 2: directly pass s, seems like it will be implicitly converted to string

istringstream strin(s);

Solution 3: explicitly convert s to string

istringstream strin((string)(s));

Solution 4: add a pair of magical parentheses

istringstream strin((string(s)));

Solution 5: tell the compiler s is indeed a char* type

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

All this works except the original one. Could anybody explain what is really going on here? Thanks.

Was it helpful?

Solution

The most vexing parse strikes again:

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

declares a function (strin) which takes a string as argument, and returns an std::istringstream. (A good compiler could warn here, because there's no way you can possible implement such a function.) The simplest way of correcting this is to add some extra parentheses:

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

(Actually, the simplest solution here is to just write:

std::stringstream strin( s );

and let the implicit conversion do the job.)

OTHER TIPS

This is the "most vexing parse" issue.

istringstream strin(string(s));

This is not a strin variable declaration but a declaration of a function taking string, returning istringstream that is named strin.

You can fix this case like this. Notice the + there. While s is identifier, +s is an expression.

istringstream strin(string(+s));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top