Skip to content

Avoid out parameters, prefer (multiple) return values

[Function returning a pair of values]
[Function returning a tuple of three values]
[Function returning a struct]

Syntactically a function/method can have a return value and additionally set some output parameters. But for an output param it is often not clear if it is an in-out param and if it should be defined as pointer or reference type. For a more clear design choose your function to return all results via its return value and completely avoid out params.

Exception: really big data may be returned more efficiently as out params, by using a reference or pointer to a data structure which is filled by the function/method.

Function returning a pair of values:

std::pair<std::string, int> FindOldestPerson()
{
    // search person e.g. within some data base
    // dbEntry = ...
    return { dbEntry.m_name, dbEntry.m_age}; // std::make_pair is not necessary
}

Client code:

// Assign return values to existing variables
std::string m_name;
int m_age;
std::tie(m_name, m_age) = FindOldestPerson();

// if you are only interested on the name
std::tie(m_name, std::ignore) = FindOldestPerson();

// With use of "structured binding" automatically create variables of appropriate type
auto [name, age] = FindOldestPerson();

Function returning a tuple of three values:

std::tuple<double, double, double> GetSomeCoords()
{
    // ...
    return { 0.1, 0.2, 0.3 }; // std::make_tuple is not necessary
}

// client code:
auto [x,y,z] = GetSomeCoords();

Function returning a struct:

struct Coord
{
    double x = 0.0;
    double y = 0.0;
    double z = 0.0;
};

Coord GetSomeCoords()
{
    // ...
    return { 2.5, 3.3 }; // struct is automatically generated
}

// client code can use named fields of struct:
auto coord = GetSomeCoords();
std::cout << "x=" << coord.x;

// client code can use structured binding:
auto [x,y,z] = GetSomeCoords();