Date: Tue, 12 Sep 2023 16:03:46 -0400
On Tue, Sep 12, 2023 at 2:16 PM Sebastian Wittmeier via Std-Proposals <
std-proposals_at_[hidden]> 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_at_[hidden]> 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
Received on 2023-09-12 20:04:01