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:
perator|(_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