Figuring out how std::optional works
Recently I was asked how is std::optional implemented. I really don’t know so I looked it up and I found this repo: https://github.com/akrzemi1/Optional which is a canonical implementation of C++17 std::optional. Now let’s dig into it and find out what it is all about.
First thing caught my eye is the implementation defines a series of type traits on its own, for example:
I have never used type traits before although I know they exists. So the above snippet is just an alias to the standard is_no_throw_constructible trait, to use this you have to use C++11’s static_assert function. Then at compile time you can determine if a type/class’ destructor throws or not, for example.
This function confused me a bit (which led to a SO question):
This is the author’s own implementation of std::forward , it uses quite complex techniques here so it is probably worth a dedicated post later. For now, all we need to know is that it serves as std:forward and I will explain later what that will do.
After a bunch of declaration we finally got to the real deal. The storage_t class that holds the underlying value:
I am not too sure what is the use of dummy_t at this moment but let’s move on. BTW there is a constexpr_storage_t class which is almost identical to this class immediately after. I am not too sure what does that do yet either. But let’s read on first.
Notice that this class is a union class and the two constructors are used for each of the data member.
The optional_base class seems just a wrapper around the storage_t class.
And this definition caught my eye:
I have never heard/used std::conditional before. But upon this point I think it is quite clear that if a type is trivially destructible then we should use constexpr version of things, but why?
Turns out for an C++ object to qualify as constexpr it cannot have an user provided deconstructor, not even an empty one. See reference here
The author’s extensive use of constexpr makes me realised that I do not know about it enough. I am now turning to a book to consult some knowledge about it, so I read through the item about it in Meyers’ Effective Modern C++. I recommend you to read it as well if you haven’t done so.
Here we should describe the actual implementation, but I still have not finished reading that part yet. And I think I need to explore further to offer something interesting. So, place holder for now :)
The unit testing of optional is interesting. The user defined a test runner using some obscure (at least to me) features. I had a bit trouble understanding it. You can read more about it here.
