On Wed, Aug 23, 2023 at 7:47 AM Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrote:
On Wed, Aug 23, 2023 at 7:39 AM Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Wed, Aug 23, 2023 at 4:10 PM Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
>
> I wonder what happened to the third strategy, which is to pass as the
> argument of existing emplace an object
> that will perform the function invocation in its conversion operator
> to the optional's element type, which then
> allows doing this without any library or language changes, and has
> field experience as a solution to this problem.


Do you mean something like the following?
GodBolt:  https://godbolt.org/z/PfM1EKaWo

Yes, but it can be done much simpler.

#include <optional>
#include <mutex>

template<class F>
struct SCSE {
F f_;
operator auto() const { return f_(); }
};

int main(void) {
std::optional<std::mutex> om;
om.emplace(SCSE([] {
return std::mutex();
}));
}

The deficiency with the current state of the world is that even SCSE doesn't help at all with returning immobile objects; you can't use SCSE to return a locked mutex, for example.

...and of course you don't need the SCSE at all, if you have a constructor that already does what you want.

https://godbolt.org/z/fWz3EzWqx

int main(void) {
std::optional<std::mutex> om;
om.emplace();
}

The reason to use the SCSE is if you have a constructor that's non-public (so `optional::emplace` can't see it), or if you have a factory-function-that's-not-a-constructor (so `optional::emplace` isn't set up to use it).

–Arthur