Reputation: 1072
I have the friends in a class definition obviously and to make it clearer, have removed the implementation code etc...
class Ref
{
public:
Ref(char* s, size_t l) : _s(s), _l(l) {}
private:
char* _s;
size_t _l;
};
class foo
{
public:
friend stringstream& operator>>(std::stringstream& s, uint8_t& v) { return s; }
friend stringstream& operator>>(std::stringstream& s, const Ref& r) { return s; }
private:
std::stringstream ss;
void example(void)
{
char b[256];
Ref r(b, sizeof(b));
uint8_t i;
ss >> i >> r; <------ Why do I get an error here?
ss >> r >> i; <------ But this one seems to compile fine.
}
};
Upvotes: 0
Views: 209
Reputation: 254751
ss >> i >> r; <------- why do I get an error here?
You forgot to tell us what the error is, or to post the actual code that gives you the error. When I fix the obvious errors in the posted code, I get:
cannot bind ‘std::basic_istream<char>’ lvalue to ‘std::basic_istream<char>&&’
The first problem is that ss >> i
won't call your overload; you can't overload the streaming operators for built-in types like uint8_t
. So this will call the overload defined by the standard library, which returns a reference to istream
, not stringstream
. Your operator expects a reference to stringstream
, so the second operator will fail.
You should follow the convention and work with a generic ostream
rather than a specific stringstream
:
friend std::istream& operator>>(std::istream& s, const Ref& r) { return s; }
If you actually want the operator to do anything useful, then you'll need to remove the const
from the second argument.
Upvotes: 1
Reputation: 154047
Why are you overloading on std::stringstream
? You should
always be overloading on std::istream
or std::ostream
(depending on the direction). It's exceedingly rare that
std::stringstream
would even be used (std::istringstream
or
std::ostringstream
would usually be more appropriate), and
even if they were, operator>>
will normally return
a std::istream&
, not a std::stringstream&
.
EDIT:
With regards to why one seemed to work:
ss >> r >> i;
is
operator>>( operator>>( ss, r ), i );
You have defined an operator>>
which takes a stringstream&
and Ref const&
, so the inner call is valid. And your
operator>>
returns a stringstream&
, which isA
std::istream
, so the function operator>>( std::istream&,
unsigned char )
can be called. Where as:
ss >> i >> r;
is
operator>>( operator>>( ss, i ), r );
The inner call returns an std::istream&
, and there is no
overloaded operator>>
for std::istream&, Ref const&
.
As stated above: overloaded >>
should always take
std::istream&
as there first argument, and return an
std::istream&
.
Upvotes: 5