Why do we use functions that return a data structure in C++?

Your question is basically: Do I return by value or do I use an output argument?

The general consensus in the community is to return by value, especially from C++17 on with guaranteed copy elision. Although, I also recommend it C++11 onwards. If you use an older version, please upgrade.

We consider the first snippet more readable and understandable and even more performant.

From a callers perspective:

std::vector<Name> names = inputNames();

It's clear that inputNames returns you some values without changing the existing state of the program, assuming you don't use global variables (which you actually do with cin).

The second code would be called the following way:

std::vector<Name> names;
 // Other code

This raises a lot of questions:

  • does inputNames use the names as input or does it extend it?
  • if there are values in names, what does the function do with it?
  • does the function have a return value to indicate success?

It used to be good practice when computers were slow and compilers had troubles optimizing, though, at this point, don't use it for output arguments.

When do you use the last style: if you want an in-out argument. In this case, if you intend to append, the vector already had data, and that actually makes sense.

This basically mirrors the mathematical definition of a function as...

...a relation that associates an input to a single output.

While you could write void functions that modify their parameters, this has disadvantages:

  • Expression of intent. Consider a function taking multiple parameters. Which ones are input, which ones are output?
  • Clarity of purpose. A function modifying multiple values at once is usually (not always) attempting to do too many things at once. Focussing on one return value per function helps with keeping your program logic under control.
  • RAII. You can't use a void function to initialize a variable, meaning you would have to declare that variable first (initialized to some "default" value), then initialize it to the desired value.

There are languages that work without return values, using "out parameters" instead. You can do it this way in C++ as well. But all in all, using return values as the one output of a function helps the structure of your program.