By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,513 Members | 1,650 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,513 IT Pros & Developers. It's quick & easy.

how to get ostream_iterator to work

P: n/a
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;
}

Nov 9 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Nan Li wrote:
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

Nov 9 '05 #2

P: n/a

Kristo wrote:
Nan Li wrote:
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::ostream_iterator<_Tp, _CharT, _Traits>&
std::ostream_iterator<_Tp,
_CharT, _Traits>::operator=(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::ostream_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::ostream_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::ostream_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::ostream_iterator<IntStringPair,
char, std::char_traits<char> >]'
........
.......

Nov 9 '05 #3

P: n/a
the real problem (besides the forgotten return value in operator<<) is
that your operator overload is not visible for
ostream_iterator::operator=(...).

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::ostream_iterator in the global namespace and use that instead,
then the operator should be found...

-- peter

Nov 9 '05 #4

P: n/a
Peter Steiner wrote:
the real problem (besides the forgotten return value in operator<<) is
that your operator overload is not visible for
ostream_iterator::operator=(...).

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::ostream_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
Nov 9 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.