We approach this systematically.
If the function is declared as T f(); , and T not void , and if the function returns normally, then it should be returned through the form instruction return e; where e is some expression.
When you evaluate the expression of the expression function f() , you get a value. Suppose U denotes an object type. If T = U & or T = U && , then the value is of type U , the expression e must be able to bind to the link, and the return value is the value of e . (The return value is also the so-called "glvalue", in terms of its category of values). In this case, nothing else happens. The function call value is the returned thing.
However, when T = U , then the value of f() is the so-called "prvalue" ("pure rvalue"), and this requires the creation of a temporary object of type U This object is constructed as if U obj = e (i.e. implicitly converted from e ). The value of f() is this temporary object. It can be used either to initialize another object (for example, U x = f(); ), or it can be attached to a link (for example, U && r = f(); ).
The binding of the returned expression e to the value of the call function occurs as the last thing inside the area of ββthe function body. It is noteworthy that this is until the end of the region, that is, before the object objects are destroyed. For example, if an exception occurs when constructing the return value object, the region must expand to destroy local objects before the exception enters the call area. Another useful illustration could be the use of secure security devices, for example. mutex locks:
U f() { std::locK_guard<std::mutex> lock(state_mutex); return state.get_value(); }
Here we assume that the initialization is U obj = state.get_value(); makes sense, and we further assume that state.get_value() should only be called when state_mutex locked. The above code does this correctly and briefly.