how to get ostream_iterator to work

N

Nan Li

Hello,
Can any one get the 'copy' statement below to work? I want it to
do the same thing as the 'for' loop does. But I got a lot of STL error
during compile.

Thanks,
Nan


#include <map>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>


using namespace std;


typedef pair<int,string> IntStringPair;


template < typename F, typename S >
ostream& operator<< ( ostream& os, const pair<F,S>& p )
{
os << p.first << " -> " << p.second ;
}


int main()
{
map<int,string> m;
m[1] = "foo";
m[2] = "bar";


for ( map<int,string>::const_iterator it = m.begin();
it != m.end();
++it ) {
cout << *it << endl;
}


//copy( m.begin(), m.end(), ostream_iterator<IntStringPair>( cout,
"\n" ) );
//why this does not work ??
return 0;
}
 
K

Kristo

Nan said:
Hello,
Can any one get the 'copy' statement below to work? I want it to
do the same thing as the 'for' loop does. But I got a lot of STL error
during compile.

Thanks,
Nan


#include <map>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>


using namespace std;


typedef pair<int,string> IntStringPair;


template < typename F, typename S >
ostream& operator<< ( ostream& os, const pair<F,S>& p )
{
os << p.first << " -> " << p.second ;
}


int main()
{
map<int,string> m;
m[1] = "foo";
m[2] = "bar";


for ( map<int,string>::const_iterator it = m.begin();
it != m.end();
++it ) {
cout << *it << endl;
}


//copy( m.begin(), m.end(), ostream_iterator<IntStringPair>( cout,
"\n" ) );
//why this does not work ??
return 0;
}

I can't be certain without seeing the list of compiler errors that you
got, but I suspect the copy() line won't compile because of the type of
IntStringPair. std::map uses a std::pair<const Key, Data> type to
store its elements. In your case, you need IntStringPair to be of type
std::pair<const int, std::string>.

Kristo
 
N

Nan Li

Kristo said:
Nan said:
Hello,
Can any one get the 'copy' statement below to work? I want it to
do the same thing as the 'for' loop does. But I got a lot of STL error
during compile.

Thanks,
Nan


#include <map>
#include <string>
#include <iostream>
#include <algorithm>
#include <iterator>


using namespace std;


typedef pair<int,string> IntStringPair;


template < typename F, typename S >
ostream& operator<< ( ostream& os, const pair<F,S>& p )
{
os << p.first << " -> " << p.second ;
}


int main()
{
map<int,string> m;
m[1] = "foo";
m[2] = "bar";


for ( map<int,string>::const_iterator it = m.begin();
it != m.end();
++it ) {
cout << *it << endl;
}


//copy( m.begin(), m.end(), ostream_iterator<IntStringPair>( cout,
"\n" ) );
//why this does not work ??
return 0;
}

I can't be certain without seeing the list of compiler errors that you
got, but I suspect the copy() line won't compile because of the type of
IntStringPair. std::map uses a std::pair<const Key, Data> type to
store its elements. In your case, you need IntStringPair to be of type
std::pair<const int, std::string>.

Kristo

I tried 'const int', but the compiler is still not happy. Here are
just the first few lines that g++ gave me and I don't get much from
those errors.

/usr/include/c++/3.2.3/bits/stream_iterator.h: In member function
`std::eek:stream_iterator<_Tp, _CharT, _Traits>&
std::eek:stream_iterator<_Tp,
_CharT, _Traits>::eek:perator=(const _Tp&) [with _Tp = IntStringPair,
_CharT =
char, _Traits = std::char_traits<char>]':
/usr/include/c++/3.2.3/bits/stl_algobase.h:228: instantiated from
`_OutputIter std::__copy(_InputIter, _InputIter, _OutputIter,
std::input_iterator_tag) [with _InputIter =
std::_Rb_tree_iterator<std::pair<const int, std::string>,
std::pair<const int, std::string>&, std::pair<const int,
std::string>*>, _OutputIter = std::eek:stream_iterator<IntStringPair,
char, std::char_traits<char> >]'
/usr/include/c++/3.2.3/bits/stl_algobase.h:260: instantiated from
`_OutputIter std::__copy_aux2(_InputIter, _InputIter, _OutputIter,
__false_type) [with _InputIter = std::_Rb_tree_iterator<std::pair<const
int, std::string>, std::pair<const int, std::string>&, std::pair<const
int, std::string>*>, _OutputIter = std::eek:stream_iterator<IntStringPair,
char, std::char_traits<char> >]'
/usr/include/c++/3.2.3/bits/stl_algobase.h:303: instantiated from
`_OutputIter std::__copy_ni2(_InputIter, _InputIter, _OutputIter,
__false_type) [with _InputIter = std::_Rb_tree_iterator<std::pair<const
int, std::string>, std::pair<const int, std::string>&, std::pair<const
int, std::string>*>, _OutputIter = std::eek:stream_iterator<IntStringPair,
char, std::char_traits<char> >]'
/usr/include/c++/3.2.3/bits/stl_algobase.h:323: instantiated from
`_OutputIter std::__copy_ni1(_InputIter, _InputIter, _OutputIter,
__false_type) [with _InputIter = std::_Rb_tree_iterator<std::pair<const
int, std::string>, std::pair<const int, std::string>&, std::pair<const
int, std::string>*>, _OutputIter = std::eek:stream_iterator<IntStringPair,
char, std::char_traits<char> >]'
........
.......
 
P

Peter Steiner

the real problem (besides the forgotten return value in operator<<) is
that your operator overload is not visible for
ostream_iterator::eek:perator=(...).

this function only honors operators in its local namespace (std::) and
the argument-dependend lookup (std:: again because of the std::pair
argument).

you would have to put the operator into the std:: namespace, which you
should not do.

better build a small wrapper class for std::pair or
std::eek:stream_iterator in the global namespace and use that instead,
then the operator should be found...

-- peter
 
J

John Harrison

Peter said:
the real problem (besides the forgotten return value in operator<<) is
that your operator overload is not visible for
ostream_iterator::eek:perator=(...).

this function only honors operators in its local namespace (std::) and
the argument-dependend lookup (std:: again because of the std::pair
argument).

you would have to put the operator into the std:: namespace, which you
should not do.

better build a small wrapper class for std::pair or
std::eek:stream_iterator in the global namespace and use that instead,
then the operator should be found...

-- peter

This is usally considerd a defect in the C++ language. Although Peter is
right that you should not put operator<< in the std namespace I wouldn't
lose too much sleep over it.

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top