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,718 of 33,346    |
|    =?ISO-8859-1?Q?Daniel_Kr=FCgler?= to Andrew Tomazos    |
|    Re: C++11 rvalue reference question    |
|    05 Dec 11 15:44:15    |
   
   c34cbae3   
   XPost: comp.lang.c++   
   From: daniel.kruegler@googlemail.com   
      
   On 2011-12-05 06:38, Andrew Tomazos wrote:   
   > class O {...};   
   > class I {...};   
   > class E {...};   
   >   
   > Suppose we have some function f that takes an instance of class I as   
   > input and produces an instance of class O as output (throwing an   
   > instance of class E on an error):   
   >   
   > O f(const I& i)   
   > {   
   > O result;   
   > ... // mutate result based on i   
   > if (...)   
   > throw E(...);   
   >   
   > return result;   
   > }   
      
   OK, so far.   
      
   > I i = ...;   
   > O o = f(i);   
   >   
   > In C++03 many times it was recommend to write such a function as   
   > follows:   
   >   
   > void f(O& out, const I& i)   
   > {   
   > .... // mutate result based on i   
   > if (,,,)   
   > throw E(...);   
   > }   
   >   
   > I i = ...;   
   > O o;   
   > f(o,i);   
   >   
   > I suspect this is to avoid the (potentially expensive) copy   
   > construction as the temporary O instance is copied from f's stack   
   > frame to the callers.   
   > The downside is that you then can't do things like:   
   >   
   > f(i).callSomeOFunction()   
   >   
   > or   
   >   
   > someFunctionTakingAnO(f(i))   
      
   Yes.   
      
   > My question is with the advent of move constructors, xvalues and   
   > rvalue references in C++11, is there anyway to address this issue?   
   >   
   > What would this mean/do:   
   >   
   > O&& f(const I& i)   
   > {   
   > O result;   
   > ... // mutate result based on i   
   > if (...)   
   > throw E(...);   
   >   
   > return result; // or std::forward(result) ?   
   > }   
   >   
   > or is it broken?   
      
   This *is* broken, for the simple reason that this will produce a   
   "dangling" reference to an automatic object that has been locally   
   created in the function and that has been destroyed before the function   
   call ends. Don't do that!   
      
   Make it simple, just use return type O (without cv-qualifiers). The   
   language has intentionally been adapted to enforce the compiler to first   
   check whether the local object "result" can be be provided as an rvalue   
   to the return statement to enable move semantics if the type provides some.   
      
   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