Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do std::optional constructors use std::in_place?

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.

like image 346
oliora Avatar asked Apr 11 '18 06:04

oliora


People also ask

What is std :: In_place?

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.

What is std :: optional for?

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.

Does STD optional allocate memory?

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 .


1 Answers

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 requesting T'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
like image 122
xskxzr Avatar answered Oct 11 '22 19:10

xskxzr