Siegfried wrote: > Here is my attempt to write a generic output function but it does not > compile. Can someone correct it for me? The problem is with the call to > widen. > > Also, is it possible to make this more generic so it is not specific to > class vector? > > Thanks, > Siegfried > > template<typename CH, typename TY> > std::basic_ostream<CH>& operator<<(std::basic_ostream<CH>& cout, const > std::vector<TY>& vec){ > std::copy(vec.begin(),vec.end(), > std::ostream_iterator<TY,CH>(cout,cout.widen(','))); > //for(typename std::vector<TY>::const_iterator pE = vec.begin(); pE > != vec.end(); pE++) cout<<(pE == vec.begin()?"[":",")<<*pE; cout > <<"]"; > return cout; > }
1. You should not specialise operator<< on a type that is not your own. vector is not your own type, so you should put in an adapter. 2. widen returns a character type, but the second parameter to ostream_iterator's constructor is const CH*. You can fix that by doing this template < typename CH, typename SQ > // where SQ is a sequence-type std::basic_ostream<CH> & operator<< ( std::basic_ostream<CH> & os // I don't like your use of cout, it's confusing const SQ & seq ) { CH delim[2]; typedef typename seq::value_type TY; delim[0] = os.widen( ',' ); delim[1] = os.widen( '\0' ); // or use the traits eos std::copy ( seq.begin(), seq.end(), // must exist for type seq std::ostream_iterator< TY >( os, delim ) ); return os; } 3. Your issue about vector - perhaps the code above will work for any sequence that has begin() and end() defined and value_type that can be output. My suggestion though is that you make your own adapter that has all these features. Of course for std::map the value_type is not your own type (it's std::pair) so either you use std::transform whenever you know it's a map and want to output it in your own way (you can specialise the above template for that case) or you have a type (value_type in your sequence) that is not the pair type in the map but has an implicit constructor from it (which would probably work). I would also suggest that instead of enforcing a comma delimiter, as you are writing your own adapter anyway you may as well allow the user to specify their delimiter and store it in the adapter. You can provide a default one. You will probably want a function to create the adapter that resolves template parameters and might even have the same name for different sequence types. Put the adapter in your own namespace and define operator<< above in the same namespace. _______________________________________________ help-gplusplus mailing list help-gplusplus@gnu.org http://lists.gnu.org/mailman/listinfo/help-gplusplus