Is there a difference between these forms: returnType vs returnType &?

Consider these free standalone functions:

std::vector<int>& f(); //reference std::vector<int> g(); //value /*const*/ std::vector<int>& f1 = f(); //reference std::vector<int> f2 = f(); //value /*const*/ std::vector<int>& g1 = g(); //reference std::vector<int> g2 = g(); //value 

Is there a difference between:

  • f () and g (). His simple question, but still I would like to hear some detailed comments on them, as this could help to understand the answer to the following questions.

  • f1 and f2. Will they be the same original objects from f (), or will f2 be a copy of the original? Exposing const will matter?

  • g1 and g2. Will they be the same original objects from g (), or will g2 be a copy of the original? Exposing const will matter?

What if f() and g() are member functions, and each returns element data, rather than some local variable? Will there be a difference in the answer to the above questions?

Try to include all errors and important points in your answer and do not consider RVO or any other optimization by the compiler. I want to know what C ++ is, not what compilers do. If you are talking about optimization, I’ll explicitly talk about it, so I don’t mix language functions with compiler functions.

+4
source share
1 answer

f() returns an object reference; returning from it does not copy any object. g() returns a copy of the object, at least conceptually.

 std::vector<int>& f1 = f(); //reference 

f1 refers to the object to which f() returns a reference. No copies are made. The const-qualification of the link does not matter here (as far as copying is concerned, obviously this affects what can be done with the object).

 std::vector<int> f2 = f(); //value 

f2 is a copy of the object to which f() returns a link.

 std::vector<int>& g1 = g(); //reference 

This is not true. A non-constant reference cannot be bound to a temporary object.

If the link is const-qualified, then this line actually matches the following line: the object returned by g() copied, the link is bound to this copy, and this copy is provided with the link lifetime (it is destroyed when the link is "destroyed").

 std::vector<int> g2 = g(); //value 

g2 is a copy of the object returned by g() . Regardless of whether a copy is made (and how many copies can be made), it depends on the optimization of the compiler.

What if f() and g() are member functions, and each returns element data, rather than some local variable?

If f() returns a link to a local variable, then the program is incorrect and gives undefined behavior if you try to use the link because the linked object ceases to exist when the function returns.

If f() returns a link to a member variable, a dynamically allocated object, or an object with a static or local thread storage duration, then the link is valid for the lifetime of this object (or for another object of the same type constructed in the same memory location as and the object to which this link was returned, although its usefulness is limited to a few select scenarios).

It doesn't matter what g() returns, because the copy always executes (at least conceptually).

+8
source

All Articles