1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
#include <iostream>
#include <string>
#include <sstream>
struct A { std::string text ; };
struct B { std::string text ; };
struct C { std::string text ; };
struct D { std::string text ; };
std::istream& operator>> ( std::istream& is, A& a ) { return is >> a.text ; }
// the library has a templated overload for operator>> ( istream&&, T& )
// which delegates to the overload for operator>> ( istream&, T& )
B& operator>>( B& b, A& a ) { b.text += '0' ; a.text = b.text ; return b ; }
// non-template overload for operator>> (B&&, A&), which delegates tooperator>> (B&, A&)
B& operator>>( B&& b, A& a ) { return b >> a ; }
C& operator>>( C& c, A& a ) { c.text += "00" ; a.text = c.text ; return c ; }
// templated overload for operator>> ( C&&, T& ) which delegates to operator>> ( C&, T& )
template < typename T > C& operator>>( C&& c, T& t ){ return c >> t ; }
D& operator>>( D& d, A& a ) { d.text += "000" ; a.text = d.text ; return d ; }
// D has no overload for operator>> ( D&&, A& )
int main()
{
std::cout << "-----------------------\n" ;
A x, y ;
// fine, uses templated overload for ( istream&&, T& ) (with T==A)
std::istringstream {"12 34 "} >> x >> y ;
std::cout << x.text << ' ' << y.text << '\n' ;
B{"56"} >> x >> y ; // fine, uses overload for ( B&&, A& )
std::cout << x.text << ' ' << y.text << '\n' ;
C{"78"} >> x >> y ; // fine, uses templated overload for ( C&&, T& ) (with T==A)
std::cout << x.text << ' ' << y.text << '\n' ;
#ifdef USE_D
D{"90"} >> x >> y ; // ***error: operator>> ( D&, A& ) expects l-value reference to D
std::cout << x.text << ' ' << y.text << '\n' ;
#endif // USE_D
std::cout << "------- done ---------\n" ;
}
|