home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 32,127 of 33,346   
   =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to James K. Lowden   
   Re: ostream_iterator for map   
   13 Apr 12 11:34:10   
   
   From: daniel.kruegler@googlemail.com   
      
   On 2012-04-13 04:46, James K. Lowden wrote:   
   > I feel like I've asked this question before, but if so I can't find   
   > it and still don't get it, so here goes....   
      
   Yes, this issue occurs once in a while.   
      
   > I want to copy a std::map to std::cout.  I define operator<< for the   
   > map's value_type.  I can use that operator by defererencing a the   
   > map's iterator.  Why can't I compile std::copy with   
   > ostream_iterator?   
   >   
   > The program that follows compiles and runs as is.  Change it to #if   
   > 0 instead, and get "no match for 'operator<<' ".  g++ says there are   
   > many candidates, all standard, none mine.   
   >   
   > The whole "no match" error is:   
   > /usr/include/g++/bits/stream_iterator.h:196: error: no match for   
   > 'operator<<' in '*((std::ostream_iterator float>, char, std::char_traits >*)   
   > this)->std::ostream_iterator, char,   
   > std::char_traits >::_M_stream<< __value'   
   >   
   > Many thanks for your insight.   
      
   ADL name-lookup wont find your operator<< overload, because it only   
   looks in namespace std, but your operator<< overload for std::pair is   
   not part of this namespace. According to the library requirements,   
   user-code shall not add any components (except template   
   specializations with at least one user-defined type) to namespace std.   
      
   The only portable way to realize this use-case is to   
      
   a) Provide an io wrapper for the wanted library-component(s)   
   b) Use std::transform instead of std::copy.   
      
   Put it all together, this may look like so:   
      
   template   
   struct pair_io {   
       const std::pair& p;   
       pair_io(const std::pair& p) : p(p) {}   
   };   
      
   template   
   inline   
   pair_io io(const std::pair& p) { return pair_io(p); }   
      
   template   
   inline   
   ostream& operator<<( ostream& os, const pair_io& value )   
   {   
       return os << "(" << value.p.first << ", " << value.p.second << ")";   
   }   
      
   and at the call point:   
      
       std::transform( m.begin(), m.end(),   
   	ostream_iterator >(cout, "\n"),   
         io);   
      
   HTH & Greetings from Bremen,   
      
   Daniel Krügler   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca