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 31,607 of 33,346   
   =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to All   
   Re: rvalues and lvalues   
   03 Nov 11 16:50:08   
   
   6eea7656   
   From: daniel.kruegler@googlemail.com   
      
   Am 03.11.2011 19:15, schrieb Jerry:   
   > How do I write a function that will accept both rvalues and lvalues?   
   >   
   > For example, if I write this (contrived example):   
   >   
   > #include   
   > #include   
   > std::vector  &  operator<<  (std::vector  &  x, const   
   > std::vector::value_type&  y)   
   > {   
   >     x.push_back(y);   
   >     return x;   
   > }   
   > int main()   
   > {   
   >     std::cout<<  (std::vector()<<  1)[0]<<  std::endl;   
   > }   
   >   
   > Then I get:   
   > Dynamo.cpp: In function 'int main()':   
   > Dynamo.cpp:12:41: error: no match for 'operator<<' in   
   > 'std::vector()<<  1'   
   > Dynamo.cpp:12:41: note: candidates are:   
   > Dynamo.cpp:4:20: note: std::vector&  operator<<(std::vector&,   
   > const value_type&)   
   > Dynamo.cpp:4:20: note:   no known conversion for argument 1 from   
   > 'std::vector' to 'std::vector&'   
   >   
   > But If I change the code to:   
   >   
   > #include   
   > #include   
   > std::vector  operator<<  (std::vector  x, const   
   > std::vector::value_type&  y)   
   > {   
   >     x.push_back(y);   
   >     return x;   
   > }   
   > int main()   
   > {   
   >     std::vector  a;   
   >     a<<  1;   
   >     std::cout<<  a[0]<<  std::endl;   
   > }   
   >   
   > Then I get a segmentation fault because the vector was copied and the   
   > change was made to the copy so the original has no 0th element.   
   >   
   > How do I write such a thing that will accept both lvalues and rvalues?   
      
   Either add an overload that takes an rvalue-reference, like so:   
      
   std::vector & operator<<(std::vector && x,   
   const std::vector::value_type & y)   
   {   
      x.push_back(y);   
      return x;   
   }   
      
      
   or replace the function by a (possibly constrained) function template that   
   uses perfect forwarding:   
      
   [your includes]   
   #include    
      
   template   
   struct is_vector_impl : std::false_type {};   
      
   template   
   struct is_vector_impl> : std::true_type {};   
      
   template   
   struct is_vector : is_vector_impl::type>   
   {   
   };   
      
   template::value>::type   
   >   
   std::vector & operator<<(T&& x,   
   const std::vector::value_type & y)   
   {   
      x.push_back(y);   
      return x;   
   }   
      
   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