std::optional
Tags: C++
std::optional defined in <optional>
header.
- standard optional is never going to do a dynamic allocation on its own. Its constructed to be at least big enough to hold the thing that you want it to hold.
#include <optional>
int main()
{
std::optional<int> i;
return sizeof(i); // have size of 8byte = size of 32bit integer + 4byte
std::optional<double> d;
d = 3.4; // no dynamic allocation happening
return sizeof(i);
}
what optional does is it is optionally set to a value it keeps track of whether or not that value is set and then it appropriately calls the destructor if it needs to.
optional::value, optional::value_or
#include <optional>
int main()
{
std::optional<int> o;
return o.value();
}
If we donโt set any value to o, we get tones of assembly instructions for handling exception.
std::optional<int> o;
return o.value_or(2);
if we use value_or like this, if o has a value it returns the value else it returns the value 2.
interesting behavior
#include <optional>
int main()
{
std::optional<int> o;
o = 12; // assigns the unset value of optional to 12
o = 14; // calling the assignment operator on the integer
return o.value_or(2);
}
In the case of integer calling an assignment is not really expensive, but in other cases like string, the code will be much more unlikely to optimize.
#include <optional>
#include <string>
int main()
{
std::optional<std::string> o;
o = std::string("Hello"); //move assignment here
return o.value().size();
}
What would happen if we have a type that cannot be moved or copied.
#include <optional>
#include <string>
struct S
{
S(const& S&) = delete;
S(S&&) = delete;
S() = default;
}
int main()
{
std::optional<S> o;
o = S(); //build error!!
}
however we could do emplace construction like o.emplace()
and it will construct our new object s in place inside optional avoiding any cost of move or copy at all.
Leave a comment