Passing by reference causes the need for many extra lines of code to be written throughout the code base, no more constants, mutating variables, other crap no one ever told you about when learning about pointers.
The solution to both of these is to use "RValue expressions".
RValues are expressions that create anonymous temporary objects.
When defining variables, using RValues allows transferring ownership of, in this case a dynamically allocated string array (vector), from the source vector to the target vector.
When using functions, returns are also anonymous temporary objects, so we transfer the resources from the return value to the target value in the same way as with variables.
Oh wait, the compiler actually takes care of optimizing stuff for you, it's called Return Value Optimization (RVO) and it works like this:
std::vector<std::string> names = get_names();
Oh shit, isn't this what we wrote as a first example that's expensive slow? yeah well, apparently there's nothing to worry about. use this.
Do pass a function within a function, because then you're passing rvalues as parameters which is unicorn-level magic
RVO optimizations aren't required by any standard, but "recent versions of every compiler I’ve tested do perform these optimizations today."
Don't pass a variable by reference and then make an explicit copy of its values - that defeats the whole purpose of what we are trying to talk to you about
Guideline: Don’t copy your function arguments. Instead, pass them by value and let the compiler do the copying.
Lesson: don't explicitly copy variable references, just get their values and the compiler will copy optimize for you
In fewer words, the argument is this
Passing by value causes a lot of under-the-hood moving and copying which is slow. but we will learn later why this is actually correct. Passing by reference causes the need for many extra lines of code to be written throughout the code base, no more constants, mutating variables, other crap no one ever told you about when learning about pointers.The solution to both of these is to use "RValue expressions". RValues are expressions that create anonymous temporary objects.
When defining variables, using RValues allows transferring ownership of, in this case a dynamically allocated string array (vector), from the source vector to the target vector.
When using functions, returns are also anonymous temporary objects, so we transfer the resources from the return value to the target value in the same way as with variables.
Oh wait, the compiler actually takes care of optimizing stuff for you, it's called Return Value Optimization (RVO) and it works like this:
Oh shit, isn't this what we wrote as a first example that's expensive slow? yeah well, apparently there's nothing to worry about. use this.Do pass a function within a function, because then you're passing rvalues as parameters which is unicorn-level magic
RVO optimizations aren't required by any standard, but "recent versions of every compiler I’ve tested do perform these optimizations today."Don't pass a variable by reference and then make an explicit copy of its values - that defeats the whole purpose of what we are trying to talk to you about
Guideline: Don’t copy your function arguments. Instead, pass them by value and let the compiler do the copying.
Lesson: don't explicitly copy variable references, just get their values and the compiler will copy optimize for you