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! */ }