When I try to declare iss using the first form, g++ gives me "error: no match for 'operator>>' in 'iss >> s'". But don't the two different declarations do the same thing?
#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); // 开发者_如何学Cbut this does
std::string s;
iss >> s;
}
This is known as the "most vexing parse" of C++: what looks like an instance declaration to you actually looks like a function declaration to the compiler.
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
Note the extra brackets in the last example. These brackets wouldn't be legal in a function declaration.
The first example with the default constructor is well-known. What adds unclarity in the second case is that brackets around parameter names in C++ are legal but optional. For example, you can define a function like this:
void foo(int (bar))
{}
Basically you'll run into this every time when all arguments to a constructor are temporaries from constructor invocations that take 0 or 1 arguments, and the quick solution is to put extra brackets around one of the arguments.
It's because istringstream
takes a const reference to a string. So you can't just write this:
std::istringstream iss(std::string(buf));
Well, actually you can, but it means you are declaring a function iss
, which takes a std::string
and returns std::istringstream
. Equivalently, you could write:
std::istringstream iss(std::string buf);
It's pretty sick C++ stuff.
I guess there is some confusion about the type returned by std::string(char*) because this:
std::istringstream iss((std::string)std::string(buf));
works.
The first argument to construct an istream from a string needs to be: const string & str which this does not create:
std::string(buf)
While the following code illustrates the point, it leaks memory, so don't actually use it.
std::istringstream iss(*new std::string(buf));
Don't you need to use namespace std;
?
精彩评论