Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation of the std::optional class

Tags:

c++

I need to implement a quick solution for optional values. I don't want to drag in any third party libraries.

How are the optional classes implemented in general? Does an optional object still default-construct the underlying object when it's in the 'null-state'?

like image 610
NFRCR Avatar asked Sep 15 '14 09:09

NFRCR


People also ask

How does STD optional work?

The class template std::optional manages an optional contained value, i.e. a value that may or may not be present. A common use case for optional is the return value of a function that may fail.

When was STD optional introduced?

std::optional was added in C++17 and brings a lot of experience from boost::optional that was available for many years. Since C++17 you can just #include <optional> and use the type. Such wrapper is still a value type (so you can copy it, via deep copy).

What is Nullopt in C++?

C++17 introduced std::optional<T> which lets you augment the values of a type T with a bonus value known as std::nullopt which semantically represents the absence of a value. A std::optional which holds the value std::nullopt is known as empty.


3 Answers

In c++14 or earlier you can use a null-checked T* or just a std::pair<T, bool>. The problem with the latter is if your default construction of T is expensive, that may be wasteful.

In c++17 or later you can still use T* but you can also use std::optional<T>. Here the latter only constructs a T if it is valid.

It's noteworthy that the std::optional is a good option in only a few cases: https://topanswers.xyz/cplusplus?q=923#a1085

like image 109
Jonathan Mee Avatar answered Oct 13 '22 18:10

Jonathan Mee


How are the optional classes implemented in general?

Typically, a boolean flag to indicate whether or not it's empty, and a suitably sized and aligned byte array to store the value.

Does an optional object still default-construct the underlying object when it's in the 'null-state'?

No; that would impose an unnecessary requirement on the stored type, as well as causing potential unwanted side-effects. The stored object would be created with placement-new when the optional becomes non-empty, and destroyed with a destructor call when it becomes empty.

For a quick-and-dirty implementation, if you don't need all the flexibility of the Boost or proposed standard versions, you could simply store a default-constructed object.

I don't want to drag in any third party libraries.

I would reconsider why you don't feel you want that. The Boost implementation is header-only, well tested, and should be directly replaceable by the standard version if and when that arrives. I'd certainly trust it more than something I cobbled together myself.

like image 35
Mike Seymour Avatar answered Oct 13 '22 18:10

Mike Seymour


First of all I highly recommend you to take a look at Boost (specifically at Boost.Optional) - it is almost standard practice to use Boost and it would save you reinventing the wheel.

If for some reason you are reluctant to use Boost.Optional, there are a bunch of similar header-only libraries, for example https://github.com/akrzemi1/Optional

like image 30
mr.pd Avatar answered Oct 13 '22 19:10

mr.pd