adding new types to cin/cout or scanf/printf

Is it possible to add new types like pairs, vectors, queues or some custom types to cin/cout or scanf/printf?
Last edited on
For cin, cout, overload operators
ostream& operator << (ostream& out, /*your type*/)
and
istream& operator >> (istream& in, /*your type reference*/)

For scanf, printf, it's not possible.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
template< typename STREAM, typename F, typename S > 
STREAM& operator<< ( STREAM& stm, const std::pair<F,S>& pair )
{ return stm << '{' << pair.first << ',' << pair.second << '}' ; }

template< typename STREAM, typename T, typename A >
STREAM& operator<< ( STREAM& stm, const std::vector<T,A>& seq )
{
    stm << "{ " ;
    for( const auto& a : seq ) stm << a << ' ' ;
    return stm << " }" ;
}


For something fancier, google 'template template parameters'.
Making the stream a template parameter is useless, it has to be an ostream in any case - unless you were planning supporting other classes that have the << operator overloaded, but those are likely to have different semantics anyways.
> it has to be an ostream in any case

Why does it have to be an ostream in any case?

Ever heard of something called std::wostream?
With the general case being std::basic_ostream<>
JLBorges:

template< typename STREAM, typename F, typename S >
STREAM& operator<< ( STREAM& stm, const std::pair<F,S>& pair )
{ return stm << '{' << pair.first << ',' << pair.second << '}' ; }

template< typename STREAM, typename T, typename A >
STREAM& operator<< ( STREAM& stm, const std::vector<T,A>& seq )
{
stm << "{ " ;
for( const auto& a : seq ) stm << a << ' ' ;
return stm << " }" ;
}


and how to use that? i dont see how to make an operator a template.
Like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <utility> // for std::pair<>

template< typename STREAM, typename F, typename S >
STREAM& operator<< ( STREAM& stm, const std::pair<F,S>& pair )
{
    return stm << stm.widen('{') << pair.first << stm.widen(',')
                << pair.second << stm.widen('}') ;
}

#include <iostream>

int main()
{
    std::pair<int,double> p( 1234, 5678.9 ) ;
    std::cout << p << '\n' ;
    std::wcout << p << L'\n' ;
}


Note: I'd carelessly missed the stm.widen() in the earlier snippet.
http://www.cplusplus.com/reference/iostream/ios/widen/
Is there a real need for stm.widen() if operator<< (specifically, template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<( std::basic_ostream<CharT,Traits>& os, char ch );) already calls it?
Last edited on
> Is there a real need for stm.widen() if
> operator<< (specifically, template< class CharT, class Traits> basic_ostream<CharT,Traits>& operator<<( std::basic_ostream<CharT,Traits>& os, char ch );)
> already calls it?

No, there is no real need - it would get called anyway. widen() is only required if one is using put().

Thanks.
ok thanks, the cout works, but what about cin?
> but what about cin?

You would be able to figure that out by yourself.

Perhaps start by reading hamsterman's post, right at the top.
I tried
1
2
3
4
5
template< typename STREAM, typename F, typename S >
    STREAM& operator>> ( STREAM& stm, const std::pair<F,S>& pair )
    {
            return stm >> &pair.first >> &pair.second ;
                }

and it doesn't work
What do you mean "doesn't work"? Does it not compile? Does it not input the values correctly? Does it make your computer start to smoke? Does yours eyes explodes whens yous runs its?
it doesn't compile, it says:
In function `STREAM& operator>>(STREAM&, const std::pair<F, S>&) [with STREAM = std::istream, F = int, S = int]':
instantiated from here
no match for 'operator>>' in 'stm >> ((const int*)pair)'
candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>&(*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
(...)
a lot more candidates
Remove the & signs from line four of the code you gave. You're not inputting to the address!
And the const from const std::pair<F,S>& pair - you can't read into a const.
Ok thanks it all works now. I used the & signes cos hamserman said istream uses reference and const cos it was cons in the first one.
Yes, but using the & signs where you used them there means address of and has to do with pointers.
Topic archived. No new replies allowed.