Some std::optional
constructors use an std::in_place_t
tag parameter like this:
template< class... Args >
explicit optional( std::in_place_t, Args&&... args );
I see that such constructors could be implemented without the in-place tag and use some enable_if
(SFINAE) magic to not participate as unwilling overloads, i.e.:
template< class... Args >
explicit optional( Args&&... args );
Why are std::optional
’s in-place constructors implemented with an std::in_place_t
tag rather than with some enable_if
magic (and no tag)?
Update: Question is slightly updated to emphasize that I realize that simply omitting the in-place tag wouldn’t work.
std::in_place is a constant of type std::in_place_t that is used to disambiguate the overloads of constructors and member functions of that take arguments (possibly a parameter pack) for in-place construction of some value.
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.
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 .
As Passer By said in the comment, the intent is to disambiguate the situation where one wants to call the default constructor of optional<T>
and the situation where one wants to call the default constructor of T
.
This intention is proposed in N3527, where the original proposed name of in_place_t
is emplace
. I quote the related part here:
We need the extra tag to disambiguate certain situations, like calling
optional
's default constructor and requestingT
's default construction:optional<Big> ob{emplace, "1"}; // calls Big{"1"} in place (no moving) optional<Big> oc{emplace}; // calls Big{} in place (no moving) optional<Big> od{}; // creates a disengaged optional
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