Where I have a choice, I prefer a reference unless the value can be maybe null.
I've taken a more "modern" approach here and prefer always using reference with a concept of Optional types if I need something nullable. Similar to the proposed C++
std::optional.
The primary difference between a reference and a pointer is that a pointer can be rebound (you can point it at something else) while a reference cannot. A reference is an alias to an object instance while a pointer is an entirely different concept (it is its own value representing a memory address). As you (almost) never actually need rebinding, you likewise almost never need pointers and can just use references most of the time. Optional types let you return a nullary value when appropriate, be it a reference (or some other non-copyable/non-moveable handle), a primitive like an int, or so on, with a unified interface for nullary checking/handling.
// a short alias
template <typename T>
using opt = std::experimental::optional<T>;
// function using optional to return either a reference or 'null'
Bar g_Bar;
opt<Bar&> foo() { return condition ? g_Bar : nullopt; }
auto bar = foo();
if (bar)
use_bar(*bar);
It'd be nice if the syntax were a little cleaner in C++, but then it'd also be nice if owning pointers (std::unique_ptr) were a built-in feature like in Rust. C++ is not for people afraid of typing or syntax spew.