Rule A8-4-8 (required, design, automated)

Output parameters shall not be used.

Rationale

Output parameters are passed to a function as non-const references or pointers that can denote either in-out or out-only parameter. Using return value prevents from possible misuse of such a parameter. Note: Prefer returning non-value types (i.e. types in a inheritance hierarchy) as std::shared_ptr or std::unique_ptr.

Example

// $Id: A8-4-8.cpp 306164 2018-02-01 15:04:53Z christof.meerwald $

#include <iostream>
#include <vector>
// Compliant, return value
std::vector<int> SortOutOfPlace(const std::vector<int>& inVec);

// Non-compliant: return value as an out-parameter
void FindAll(const std::vector<int>& inVec, std::vector<int>& outVec);

struct B
{
};

struct BB
{
    B GetB() const& { return obj; }
    B&& GetB() && { return std::move(obj); }

    B obj;

};

// Non-compliant: returns a dangling reference
BB&& MakeBb1()
{
    return std::move(BB());
}

// Compliant: uses compiler copy-ellision
BB MakeBb2()
{
    return BB();

}

int main()
{
    BB x = MakeBb2();

    auto cpd = x.GetB();
    // copied value
    auto mvd = MakeBb2().GetB(); // moved value

    return 0;

}

See also

C++ Core Guidelines [11]: F.20: For ”out” output values, prefer return values to output parameters.