stl ostream_iterators with user defined types

G

grahamo

Hi,

I am trying to use STL copy routine to stream the my user defined type
to std out. I am using a standard ostream_iterator object in
conjunction with my type (called employee) which has

friend std::eek:stream& operator<< (std::eek:stream &os, const employee&
e);

correctly implemented and I am therefore able to do things like;

cout << employee_instance << endl;

however I have a collection of my employee objects populating an STL
map and what I now want to be able to do is this;

copy (my_employee_map.begin(), my_employee_map.end(),
ostream_iterator<employee> (cout, " ") );


however I am getting all sorts of compile time errors. (they're below
but you probably don't want to see them :)


I am fairly sure there's something needed in my employee class in
order to get the line of code;

copy (my_employee_map.begin(), my_employee_map.end(),
ostream_iterator<employee> (cout, " ") );

to work correctly.

Any ideas?

thanks much,

GrahamO



Compiler: gnu
Building Makefile: "C:\cygwin\projects\stl\Makefile.win"
Executing make...
make.exe -f "C:\cygwin\projects\stl\Makefile.win" all
g++.exe -c main.cpp -o main.o -I"C:/cygwin/usr/include"
In file included from /usr/include/c++/3.3.1/backward/defalloc.h:58,
from main.cpp:10:
/usr/include/c++/3.3.1/backward/backward_warning.h:32:2: warning:
#warning This file includes at least one deprecated or antiquated
header. Please consider using one of the 32 headers found in section
17.4.1.2 of the C++ standard. Examples include substituting the <X>
header for the <X.h> header for C++ includes, or <sstream> instead of
the deprecated header <strstream.h>. To disable this warning use
-Wno-deprecated.
/usr/include/c++/3.3.1/bits/stl_algobase.h: In function `_OutputIter
std::__copy(_InputIter, _InputIter, _OutputIter,
std::input_iterator_tag)
[with _InputIter = std::_Rb_tree_iterator<std::pair<const int,
employee>,
std::pair<const int, employee>&, std::pair<const int, employee>*>,
_OutputIter = std::eek:stream_iterator<EMPLOYEE, char,
std::char_traits said:
/usr/include/c++/3.3.1/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, employee>, std::pair<const
int, employee>&, std::pair<const int, employee>*>, _OutputIter =
std::eek:stream_iterator<EMPLOYEE, char, std::char_traits<char> >]'
/usr/include/c++/3.3.1/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, employee>, std::pair<const
int, employee>&, std::pair<const int, employee>*>, _OutputIter =
std::eek:stream_iterator<EMPLOYEE, char, std::char_traits<char> >]'
/usr/include/c++/3.3.1/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, employee>, std::pair<const
int, employee>&, std::pair<const int, employee>*>, _OutputIter =
std::eek:stream_iterator<EMPLOYEE, char, std::char_traits<char> >]'
/usr/include/c++/3.3.1/bits/stl_algobase.h:349: instantiated from
`_OutputIter std::copy(_InputIter, _InputIter, _OutputIter) [with
_InputIter = std::_Rb_tree_iterator<std::pair<const int, employee>,
std::pair<const int, employee>&, std::pair<const int, employee>*>,
_OutputIter = std::eek:stream_iterator<EMPLOYEE, char,
std::char_traits<char> >]'
main.cpp:296: instantiated from here
/usr/include/c++/3.3.1/bits/stl_algobase.h:228: error: no match for
'operator='
in '(&__result)->std::eek:stream_iterator<_Tp, _CharT,
_Traits>::eek:perator*()
[with _Tp = EMPLOYEE, _CharT = char, _Traits =
std::char_traits<char>]() =
(&__first)->std::_Rb_tree_iterator<_Val, _Ref, _Ptr>::eek:perator*()
const
[with _Val = std::pair<const int, employee>, _Ref = std::pair<const
int,
employee>&, _Ptr = std::pair<const int, employee>*]()'
/usr/include/c++/3.3.1/bits/stream_iterator.h:140: error: candidates
are:
std::eek:stream_iterator<_Tp, _CharT, _Traits>&
std::eek:stream_iterator<_Tp,
_CharT, _Traits>::eek:perator=(const _Tp&) [with _Tp = EMPLOYEE,
_CharT = char,
_Traits = std::char_traits<char>]
/usr/include/c++/3.3.1/bits/stream_iterator.h:119: error:
std::ostream_iterator said:
::eek:perator=(const std::eek:stream_iterator<EMPLOYEE, char,
std::char_traits<char> >&)
make: *** [main.o] Error 1
Execution terminated
 
D

David Harmon

however I have a collection of my employee objects populating an STL
map and what I now want to be able to do is this;

copy (my_employee_map.begin(), my_employee_map.end(),
ostream_iterator<employee> (cout, " ") );

std::map iterators do not point to value_type instances. Rather, they
point to std::pair<const key_type, value_type>. So there is insufficient
glue between your map iterators and the output.

I think the simplest bit of glue to add would be your own version of
operator<< for the pair type.
 
T

Thomas Wintschel

David Harmon said:
std::map iterators do not point to value_type instances. Rather, they
point to std::pair<const key_type, value_type>. So there is insufficient
glue between your map iterators and the output.

I think the simplest bit of glue to add would be your own version of
operator<< for the pair type.

transform is a generalized form of copy that allows you to operate on
each element and write the result to the output range. select2nd
returns the second element of a pair. Combining the two (and assuming
your key_type is an int):

transform (my_employee_map.begin(), my_employee_map.end(),
ostream_iterator<employee> (cout, " "),
select2nd<map<int, employee>::value_type>() );

Merry day
Tom
 
D

David Harmon

transform is a generalized form of copy that allows you to operate on
each element and write the result to the output range. select2nd
returns the second element of a pair. Combining the two (and assuming
your key_type is an int):

transform (my_employee_map.begin(), my_employee_map.end(),
ostream_iterator<employee> (cout, " "),
select2nd<map<int, employee>::value_type>() );


That's good. I guess select2nd will probably be incorporated in a
future C++ standard, meanwhile it appears to be widespread.
http://www.sgi.com/tech/stl/select2nd.html
http://www.sgi.com/tech/stl/stl_function.h


template <class _Pair>
struct _Select2nd
: public unary_function<_Pair, typename _Pair::second_type>
{
const typename _Pair::second_type& operator()(const _Pair& __x) const
{
return __x.second;
}
};
 

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,968
Messages
2,570,150
Members
46,696
Latest member
BarbraOLog

Latest Threads

Top