Re: Why extracting string from stringstream(a) fails?
On 25/10/09 06:17, Mc Lauren Series wrote:
On Oct 25, 3:28 am, Victor Bazarov<v.Abaza...@comAcast.net> wrote:
Mc Lauren Series wrote:
#include<iostream>
#include<sstream>
using namespace std;
int main()
{
string a("test");
string b;
stringstream(a)>> b;
}
When I try to execute this code, I get errors:
foo.c: In function 'int main()':
foo.c:10: error: no match for 'operator>>' in
'std::basic_stringstream<char, std::char_traits<char>,
std::allocator<char> >(((const std::basic_string<char,
std::char_traits<char>, std::allocator<char> >&)((const
std::basic_string<char, std::char_traits<char>, std::allocator<char>
*)(& a))), std::operator|(_S_out, _S_in))>> b'
Why does this error occur? Isn't stringstream(a) supposed to behave
just like a stream? With cout I can extract string into a string
variable. Then why not here?
The operator>> is a non-member. It takes the first argument by a
non-const reference, which cannot be initialized with a temporary.
Define a named variable and you will be able to do what you want:
stringstream sa(a);
sa>> b;
There is a trick to overcome this particular limitation, but it's not
the best approach. You can do something like that
stringstream(a)>> boolalpha>> b;
which invokes a non-const member function (which is OK for temporaries)
and the function (that "outputs" a manipulator) returns a non-const
reference, which then can be passed to the non-member operator<<.
If>> is a non-member, why does this work?
Some stream operators are member functions, others are not. Member
functions can be called on temporary objects. boolalpha is handled by a
member function which returns std::istream&. That std::istream& can than
be accepted by both member and non-member operator>> functions.
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main()
{
string a("1234");
// string b;
int b;
stringstream(a)>> b;
cout<< b<< endl;
}
If we change the data type of b to int, the code works fine but not
with b as string. Why?
Because extracting into an integer is handled by a member function of
std::istream base class of std::stringstream.
Here is another trick to turn a temporary into an l-value, so that any
operator>> can work on a temporary stream object:
template<class T>
inline T& lvalue(T const& t) {
return const_cast<T&>(t);
}
This function template is supposed to be used like this:
lvalue(stringstream(a)) >> ...;
Alternatively, boost::lexical_cast<> converts between types using
streams and its usage is simpler:
int b = boost::lexical_cast<int>("1234");
Using streams directly as you do allows to extract more than one value
at once though.
--
Max