My notation and notation provided in the previous message would be like

 

P2025R2 Guaranteed copy elision for named return objects by Anton Zhilin together with §8.2.2 Require an explicit mark at the variable declaration variant 2.
 

-----Ursprüngliche Nachricht-----
Von: Arthur O‘Dwyer via Std-Proposals <std-proposals@lists.isocpp.org>
Gesendet: Mi 13.09.2023 17:19
Betreff: Re: [std-proposals] Copy-construct, move-construct, and PR-construct
An: std-proposals@lists.isocpp.org;
CC: Arthur O‘Dwyer <arthur.j.odwyer@gmail.com>;
On Tue, Sep 12, 2023 at 2:16 PM Sebastian Wittmeier via Std-Proposals <std-proposals@lists.isocpp.org> wrote:

Should we have unmovable-and-uncopiable return values at all?

 

Even if it can be technically solved for certain cases, those classes are not meant to be moved, copied or returned.

 
s/or returned//
I'd say that such types were always meant to be supported (because why wouldn't they be?), and since C++17 immovable return types have been supported, at least in the cases that Just Work (like `return std::mutex();`). One certainly can't say that std::mutex wasn't "meant" to be returned. It's a class type; of course you can return it from a function! (In spirit, although not literally, each constructor of std::mutex is such a function.)
 

Better change the interface of std::optional::emplace and/or SomeFunctionThatReturnsMutex().

So that

 - SomeFunctionThatReturnsMutex gets a pointer, where to construct its mutex and

 - emplace gets a Callable, which creates the mutex at the right moment in time

 
The problem with that kind of "two-stage initialization" is that it doesn't lend itself to value semantics. You're suggesting that I should write
    std::mutex *lockedMutexFactory(void *where) { auto *p = ::new (where) std::mutex(); p->lock(); return p; }
    alignas(std::mutex) char buf[sizeof(std::mutex)];
    std::mutex *m = lockedMutexFactory(buf);
    use(*m);
    m->~mutex();
but what I really want to write is
    std::mutex lockedMutexFactory() { std::mutex m; m.lock(); return /*somehow*/ m; }
    use(lockedMutexFactory());
 
Now, I don't think any of the half-proposed ideas in this thread so far have been good.
But I disagree with the notion that we should somehow desire two-stage initialization just because one of our types happens to be immovable.
 
FVG wrote:
   optional<mutex> om;

   om.emplace( SomeFunctionThatReturnsMutex() );

Currently we can't do this, and it's something that needs to change.
We can do this fine; use the SCSE pattern.
The things we currently can't do are:
- Implement SomeFunctionThatReturnsMutex() in the first place, unless it's happy with URVO (i.e. just calls a ctor, or another factory, and does nothing else before returning)
- Do this dance for a hypothetical immovable type that is convertible-from any T
 
my $.02,
Arthur
-- 
 Std-Proposals mailing list
 Std-Proposals@lists.isocpp.org
 https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals