C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::elide

From: Robert A.H. Leahy <rleahy_at_[hidden]>
Date: Fri, 31 May 2024 13:05:06 +0000
I don't understand how you get from using two language features (user overloadable implicit conversion operators and C++17 guaranteed RVO) in concert to "trick[ing] rvo."

--Robert
________________________________
From: Tiago Freire <tmiguelf_at_[hidden]>
Sent: Friday, May 31, 2024 01:46
To: Robert A.H. Leahy <rleahy_at_[hidden]>
Cc: std-proposals_at_[hidden] <std-proposals_at_[hidden]>
Subject: Re: [std-proposals] std::elide

There you go, now we are getting there. What you want is to trick rvo.
Why not make that explicit? Are we afraid to run out of function names?

________________________________
From: Robert A.H. Leahy <rleahy_at_[hidden]>
Sent: Friday, May 31, 2024 1:25:09 AM
To: Tiago Freire <tmiguelf_at_[hidden]>
Cc: std-proposals_at_[hidden] <std-proposals_at_[hidden]>
Subject: Re: [std-proposals] std::elide

Passing an rvalue requires there be some object with storage to bind the reference to. The primary use case of std::elide is for when you want to materialize a prvalue directly into storage (say, for example, to initialize something immovable).

--Robert

On May 30, 2024 19:22, Tiago Freire <tmiguelf_at_[hidden]> wrote:
No, the real issue is that you want to call a function instead of passing an object, and you want to do that using passing an object semantics. You are hoping that compiler magic would figure out what you want without writing what you want.

Ps you can pass an rvalue to the emplace of a std::optional so why is it again that you need an std::elide?

________________________________
From: Robert A.H. Leahy <rleahy_at_[hidden]>
Sent: Friday, May 31, 2024 1:07:29 AM
To: Tiago Freire <tmiguelf_at_[hidden]>; std-proposals_at_[hidden] <std-proposals_at_[hidden]>
Subject: Re: [std-proposals] std::elide

As you point out later in your own email emplace does not "forward[] arguments to a constructor." It forwards arguments to an expression which initializes an object. This initialization may call a constructor, or it may call a conversion operator and materialize a prvalue (as in the case of std::elide).

If std::elide is objectionable, then so is using emplacement construction with anything that implicitly converts to the destination type, which is a characterization that I think most people would reject.

You're correct that templated constructors can be greedy and thereby be selected in places that were arguably unintended. Fortunately we have techniques (including concepts) to deal with this so this is only really an issue for wrapper types whose constructors aren't appropriately constrained. This is an issue regardless of whether or not std::elide exists.

The real issue with std::elide is how it interacts with CTAD. But there are also solutions for this which don't involve core language changes.

--Robert
________________________________
From: Tiago Freire <tmiguelf_at_[hidden]>
Sent: Thursday, May 30, 2024 18:52
To: Robert A.H. Leahy <rleahy_at_[hidden]>; std-proposals_at_[hidden] <std-proposals_at_[hidden]>
Subject: Re: [std-proposals] std::elide

> Why would we create a new interface for invocation, and then add it to each and every container type, duplicating each and every API which defers responsibility for construction, when the language gives us a mechanism (this one) that works just fine for the purpose?

I disagree, there's no such mechanism.
What you have is an emplace that forwards arguments to a constructor. What this does is to take advantage of a hole in the template metaprogramming to forward an object that is not one that is accepted by the constructor. It then tricks the language to issue a cast (that happens implicitly) instead which in this case invokes a custom function. But this hackery doesn't work completely, because if the constructor is templated it will just accept the object without trying to cast it, cocking it up.
And because it is cocked up, he now wants to add an exception to the core language, so that templates stop working for this special class in order to cover the cock up.



> Note that there's no difference between deferring construction and using the proposed std::elide, and constructing the class directly.

And if that's the case that begs the question as to why you would to use it in the first place?
This is a very good question, why would you use it in the first place?
Every way that is possible to construct the object, you can do it using emplace. So why do you need it?
Why should I accept this wart?



Received on 2024-05-31 13:05:11