Quick tip: How to return std::optional from a function

Here’s a template for returning a std::optional from a function:

#include <optional>
// Remember to compile with --std=c++17 or equivalent

std::optional<double> myOptionalFunction() {
    auto myValue = /* ... */;
    if(myValue.IsNull()) {
        // We don't have a value
        return std::nullopt; // .has_value() => false
    }
    // We have a value, so return the value
    return myValue.AsDouble(); // .has_value() => true
}

std::nullopt is the easy way to return no value as a std::optional. Using this method instead of the default constructor (return std::optional<double>() in this case) you don’t explicitly have to enter the full qualified name including template argument (optional<double> if you use namespace std;). It’s much easier to read and copy&paste this way.

In the last line we can just return a double (myValue.AsDouble() in this example). Why? Because this will implicitly call the implicit constructor of std::optional<double>(const double& value) and therefore convert your double into a std::optional<double>() instance.

Usage example:

#include // std::optional
#include  // std::cerr, std::endl

using namespace std;

std::optional myOptionalFunction() {
    /* Your code goes here ! */
}

int main() {
    auto myOptionalValue = myOptionalFunction;
    if(myOptionalValue.has_value()) {
         // Print error message
         cerr << "The optional has no value!" << endl;
         return;
    }
    // Extract the value
    auto myValue = myOptionalValue.value();
    /* You can do something with myValue here! */
}

Alternatively you can use std::optional<T>::value_or() like this to give either the value or a default value:

#include <optional> // std::optional
#include <iostream> // std::cerr, std::endl

using namespace std;

std::optional<double> myOptionalFunction() {
    /* Your code goes here ! */
}

int main() {
    auto myOptionalValue = myOptionalFunction;
    const double defaultValue = 0.0;
    // Value will be 0.0 if myOptionalFunction() returned <no value>
    auto myValue = myOptionalValue.value_or(defaultValue);
    /* You can do something with myValue here! */
}