C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::elide

From: Jens Maurer <jens.maurer_at_[hidden]>
Date: Sun, 10 Mar 2024 16:34:40 +0100
On 10/03/2024 15.28, Frederick Virchanza Gotham via Std-Proposals wrote:
>> So, without the core language change, if AwkwardClass ever wants to
>> participate in no-copy creation, it would need to add a requires-clause.
>
>
> Yes, the template constructor would need the following constraint:
>
> requires (!is_specialization_v<remove_cvref_t<T>, elide_t>)
>
>
>> Seems a small price to pay.
>
>
> But the whole point of all of this is that we don't have to edit the
> original classes such as std::optional, std::variant, boost::whatever.

The standard owns std::optional and std::variant, so asking the
standard library to cooperate with another standard library
component seems the most straightforward approach. Same for
third-party components, if they so desire.

For example, we introduced std::span or std::filesystem::path
and then gradually updated various existing components such
as std::ifstream.

> If the class has a canonical 'emplace' method, then this proposal can
> enable us to elide the copy/move operation without the need to edit
> the original class definitions.

> If we can edit the original class definitions then we may as well just
> add a method called 'emplace_with_return_value_from_invocation_of'.

We can. We define the standard library, that's our purpose.
>> I'd like to point out that we already have std::piecewise_construct for
>> a similar purpose.
>
>
> Interesting, I hadn't seen this before. A good example of where the
> distinction between language and library has become mushed.

How so? std::piecewise_construct is entirely a library facility.

>> For the avoidance of doubt, I'm opposed to the core language change.
>
>
> Until you're dealing with allocators. The below code will invoke the
> constructor of 'MonkeyAllocator' with T set to a specialisation of
> 'std::elide_t' -- which of course we don't want.
>
> class Monkey {};
>
> struct MonkeyAllocator : std::allocator<Monkey> {
> std::mutex m; // cannot move, cannot copy
>
> template<typename T>
> MonkeyAllocator(T &&arg) : std::allocator<Monkey>( std::forward<T>(arg) )
> {
> cout << "MonkeyAllocator constructed with T = " <<
> typeid(T).name() << endl;
> }
> };
>
> MonkeyAllocator GiveMeMonkeyAllocator(void)
> {
> return MonkeyAllocator( std::allocator<int>() );
> }
>
> int main(void)
> {
> std::optional<MonkeyAllocator> var;
> var.emplace( std::elide(GiveMeMonkeyAllocator) );
> }

What's wrong with var.emplace(std::allocator<int>()) ?
This won't move a MonkeyAllocator around, I believe.

Jens

Received on 2024-03-10 15:34:47