std::optional from C++17 vs custom type for optional value

Pierre Gradot - Nov 25 '20 - - Dev Community

C++17 has introduced a very useful template class, std::optional:

The class template std::optional manages an optional contained value, i.e. a value that may or may not be present.

I have been using this feature a lot since 2017, even for a simple optional integer. Today, I got curious: is this template type effective compared to an equivalent type that I would write myself to achieve the same behavior?

Good question, thank you 😆

Let's try to write some code and use Compiler Explorer to compare both solutions: std::optional vs custom type for optional value.

First, let's define two equivalent types:

#include <optional>

using StdOptionalInt = std::optional<int>;

struct CustomOptionalInt {    
    bool has_value;
    int value;
};
Enter fullscreen mode Exit fullscreen mode

Then, let's write two functions that test if the value is available and return either this value (if available) or a default value (if not available):

int getStdOptional(const StdOptionalInt& o) {
    return o.has_value() ? o.value() : 0;
}

int getCustomOptional(const CustomOptionalInt& o) {
    return o.has_value ? o.value : 0;
}
Enter fullscreen mode Exit fullscreen mode

Finally, compile the code with Compiler Explorer and compare the output assembly codes (you can try by yourself here):

with_compiler_explorer

Yeah! 😃 The 2 functions generate the same assembly code. There is no difference of performance. Notice the static assertion at the end of the source code: because the code compiles, it means the footprint are the same. The behavior is the same with gcc and clang for x86-64.

As a conclusion, std::optional is as efficient as a custom type to represent an optional integer value. Don't implement your own type, simply use the standard type. You may even get better performance using std::optional, as explained on cppreference:

As opposed to other approaches, such as std::pair<T,bool>, optional handles expensive-to-construct objects well and is more readable, as the intent is expressed explicitly.


By the way, if you happen to speak French:

  • I wrote an article to explain to how to use std::optional.
  • I made a video to present Compiler Explorer.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player