Best alternative to std::optional to return an optional value from a method? (using C++98/C++11/C++14)

Viewed 13721

Obviously, std::optional is the best choice to return an optional value from a function if one uses C++17 or boost (see also GOTW #90)

std::optional<double> possiblyFailingCalculation()

But what and why would be the best alternative if one is stuck with an older version (and can't use boost)?

I see a few options:

  1. STL smart pointers (C++11 only)

    std::unique_ptr<double> possiblyFailingCalculation();
    
    • (+) virtually the same usage as optional
    • (−) confusing to have smart pointers to non-polymorphic types or built-in types
  2. Pairing it up with a bool

    std::pair<double,bool> possiblyFailingCalculation();
    
  3. Old style

    bool possiblyFailingCalculation(double& output);
    
    • (−) incompatible with new C++11 auto value = calculation() style
  4. A DIY template: a basic template with the same functionality is easy enough to code, but are there any pitfalls to implement a robust std::optional<T> look-a-like template ?

  5. Throw an exception

    • (−) Sometimes "impossible to calculate" is a valid return value.
3 Answers

instead of std::optional, use tl::optional from this link: https://github.com/TartanLlama/optional

It has the same public interface as its std counterpart, only it compiles in C++98 also.

I used it in production code (C++11) and works great!

I'd also consider a sentinel value.

In the case of a double the NaN value (std::numeric_limits<double>::quiet_NaN()) is a possible candidate (only meaningful if std::numeric_limits<double>::has_quiet_NaN == true).

There are various opinions about this approach (e.g. take a look at NaN or false as double precision return value and Good sentinel value for double if prefer to use -ffast-math).

In specific domains there could be other meaningful sentinel values.

In any case (not only for double) I'd adopt/implement something like markable (https://github.com/akrzemi1/markable) to avoid magic values and indicate that the value may not be there and that its potential absence should be checked by the user.

For additional motivation and overview of this approach: Efficient optional values.

Related