== The Problem == Boost.Range defines boost:: begin to give you the iterator to every possible container — except ostream. == Solution 1 == === Implementation === I have the following function for you to add to Boost.Range: template < class P_I, class P_C, class P_T > std:: ostream_iterator < typename boost:: iterator_value < P_I >:: type, P_C, P_T > begin (std:: basic_ostream < P_C, P_T > &p_s, P_I const &, P_C const p_p [] = NULL) { return std:: ostream_iterator < typename boost:: iterator_value < P_I >:: type, P_C, P_T > (p_s, p_p); } === Application === to be used in the following way: void foo (std:: vector < int > const &v) { boost:: copy (v, boost:: begin (std:: cout, boost:: begin (v), " "); } This function eliminats the need of passing explicit template parameters to std:: ostream_iterator, which makes the code fragile and hard to read. == Solution 2 == === Motivation === Since an output stream iterator is not useful except for copying to an output stream, a further simplification is also possible: === Implementation === template < class P_R, class P_C, class P_T > std:: basic_ostream < P_C, P_T > © (P_R const &p_r, std:: basic_ostream < P_C, P_T > &p_s, P_C const p_p [] = NULL) { copy (p_r, std:: ostream_iterator < typename boost:: range_value < P_R >:: type, P_C, P_T > (p_s, p_p)); return p_s; } === Application === and it enables the following invocation: void foo (std:: vector < int > const &v) { boost:: copy (v, std:: cout, " "); } Please consider. Chris