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