On Wed, Aug 23, 2023 at 7:10 AM Ville Voutilainen via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Wed, 23 Aug 2023 at 18:07, Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org> wrote:

> If we are to be able to put a PRvalue inside an std::optional in
> C++26, then there's two ways of going about it:
> Strategy 1:  Give std::optional a new member function such as
> 'PRemplace', to which you pass a function pointer to allow it to
> invoke the function and put the return value in a pre-allocated
> buffer.
> Strategy 2:  Give us PR-construction and PR-assignment.
>
> I'm leaning toward Strategy 2.

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.

That's the "super-constructing super-elider"
https://quuxplusone.github.io/blog/2018/05/17/super-elider-round-2/
and it already works great and needs no help from the paper standard... except in the specific use-case this thread keeps drifting around, which is when you want to construct an immobile object and do something with it before yielding it back to your caller.

    std::mutex returnLockedMutex() {
        std::mutex m;
        m.lock();
        [[nrvo]] return m;  // fantasy syntax, doesn't compile today because m isn't move-constructible
    }
    int main() {
        std::mutex m = returnLockedMutex();  // OK
    }

The SCSE doesn't help with this use-case.
You can already put a mutex into an optional just fine, but you can't put a locked mutex anywhere — not into an optional, not into a plain old variable, nowhere.

–Arthur