This is a matter of style. At Google (see Google C++ style guidelines), the following would be preferred:
bool CalculateSomeValue(
const vector<string>& input, map<string, double>* result);
This is because using a pointer requires the explicit use of an ampersand at the call site:
CalculateSomeValue(input, &result);
As opposed to the way it would be invoked with a reference type:
CalculateSomeValue(input, result);
By forcing the use of an ampersand in cases where parameters are modified, it is clear at the call site what will happen. When using references, it becomes necessary to lookup the documentation for each and every function to know whether it has the potential to modify its input parameters.
However, the use of a pointer has its downsides, too. In particular, the use of a pointer means that you shift responsibility of handling null from the caller where the pointer would be dereferenced (if the variable is a pointer and not merely an address-of expression with a local variable) to the function. That is, when using a pointer type, CalculateSomeValue
needs to check for nullptr
(or needs to clearly document that it requires this checking in the caller), whereas the use of a reference type is self-documenting and clearly indicates that a non-null reference is expected.
For this particular situtation, I personally highly recommend a hybrid approach:
bool CalculateSomeValue(
const std::vector<std::string>& input,
Output<map<string, double>> result);
... where Output<T>
is created by a function with the signature:
template<typename T> Output<T> WriteTo(T& output_ref);
... and where Output<T>
overloads operators ->
, *
, etc. This basically forces the call sites to be explicit in the fact that the input will be mutated by requiring:
CalculateSomeValue(input, WriteTo(result));
... as opposed to:
CalculateSomeValue(input, result);
... while simultaneously gaining the non-null semantics/syntax of references.