Consider the classes
struct Foo1
{
int n;
double m;
};
and
struct Foo2
{
std::optional<int> n;
std::optional<double> m;
};
In reality the number of members is greater than this. Is there a way I can templatise this to one class, something like
template<class T>
struct Foo
{
T<int> n;
T<double> m;
};
where if T
is std::optional
then Foo
is the same as Foo2
, and if T
is "nothing at all" then it's the same as Foo1
. They don't have to be formally the same, just have the same member types if you get my meaning.
So then I could write Foo<std::optional> foo2;
in order to make all the members optional or Foo<whatever> foo1;
to make them not optional.
I'm using C++14, although if this requires techniques beyond that standard, I'll live with it!
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.
According to the standard std::optional is prohibited to use dynamic memory for their direct members.
What's more, std::optional doesn't need to allocate any memory on the free store. std::optional is a part of C++ vocabulary types along with std::any , std::variant and std::string_view .
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.
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’s more, std::optional doesn’t need to allocate any memory on the free store. std::optional is a part of C++ vocabulary types along with std::any, std::variant and std::string_view.
So we shouldn’t spell “optional T& ” as std::optional<T&>, it should be spelt differently. I’d argue it should be called std::optional_arg<T>, because that reflects the actual use case it’s going to get. In my opinion we don’t need std::optional<T&> . It is a weird type with only very few use cases.
For additional examples, you could look at the boost::optional documentation. boost::optional and std::optional will basically be identical in terms of behavior and usage. Show activity on this post. Show activity on this post.
Modern C++ Features - std::optional - Simplify C++! Sometimes we want to express the state of “nothing meaningful” instead of a value. This is the use case for C++17’s std::optional. In programming, we often come across the situation that there is not always a concrete value for something.
You can write a simple switch that chooses between a type or its optional:
template <typename T, bool O = false>
using optionally_optional = std::conditional_t<O, std::optional<T>, T>;
And then, use it as follows:
template <bool O>
struct Foo
{
optionally_optional<int, O> n;
optionally_optional<double, O> m;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With