C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::construct<T>

From: Avi Kivity <avi_at_[hidden]>
Date: Tue, 03 Dec 2024 12:38:11 +0200
That's a peculiarity of pin<> and isn't related to construct<>.

The problem with pin<> will happen anywhere you use perfect forwarding,
for example you can't use it with std::apply(). Just because one class
is broken wrt perfect forwarding doesn't mean we can't use perfect
forwarding any more.


On Mon, 2024-12-02 at 11:49 +0000, Gašper Ažman wrote:
> `pin` is a common but not-standardized wrapper that forbids moving or
> copying. It's the common way of saying "the address of this object is
> stable and it won't move".
>
> To a first approximation, `pin` looks like this (I'm omitting all the
> common tricks to get direct initialization to work etc):
>
> ```
> template <typename T>
> struct pin {
> T value;
>
> pin(pin&&) = delete;
> pin(pin const&) = delete;
> auto operator=(pin&&) = delete;
> auto operator=(pin const&) = delete;
> };
> ```
>
> And yes, all wrappers have this problem, but other than `emplace` and
> `apply`, they store the values in between so there's nothing to be
> done about that. Effectively the problem is correctly forwarding pr-
> values.
>
> You can get around it by having a helper such as
> ```
> template <typename... Ts>
> struct emplace {
> std::tuple<Ts...> args;
> template <typename T>
> auto operator T() && {
> return T{std::get<i>(std::move(args))...}; // expand on Ts,
> you need a lambda but I'm too lazy to write it
> }
> };
> ```
> It's also not the full helper, there's a paper and I forget what it's
> called, but that's the best we can do with perfect-forwarding right
> now and it's sad.
>
> On Mon, Dec 2, 2024 at 11:02 AM Avi Kivity <avi_at_[hidden]> wrote:
> > What's pin<int>?
> >
> > Don't all helpers that rely on perfect forwarding suffer from this?
> > e.g. std::bind(), std::bind_front(), emplace()?
> >
> > Shouldn't we rename "perfect forwarding" to "imperfect forwarding"
> > if it isn't able to perfectly forward some types?
> >
> > On Sun, 2024-12-01 at 19:31 +0000, Gašper Ažman via Std-Proposals
> > wrote:
> > > The only reason to standardize this would be if somehow this
> > > function was magically blessed to perfectly forward constructor
> > > arguments to the constructor, including non-movable pr-values:
> > >
> > > MyType(pin<int>)
> > >
> > > is not constructible using std:construct without special language
> > > support.
> > >
> > > On Sun, Dec 1, 2024 at 7:28 PM Andrey Semashev via Std-Proposals
> > > <std-proposals_at_[hidden]> wrote:
> > > > On December 1, 2024 9:43:24 PM Avi Kivity <avi_at_[hidden]>
> > > > wrote:
> > > >
> > > > > On Sun, 2024-12-01 at 21:25 +0300, Andrey Semashev wrote:
> > > > >> On December 1, 2024 7:57:45 PM Avi Kivity <avi_at_[hidden]>
> > > > wrote:
> > > > >>
> > > > >>> On Sun, 2024-12-01 at 19:11 +0300, Andrey Semashev via Std-
> > > > >>> Proposals
> > > > >>> wrote:
> > > > >>
> > > > >>> Or we can make it a
> > > > >>> niebloid.
> > > > >>
> > > > >> Sorry, I don't know what this means.
> > > > >
> > > > >
> > > > > A technique used in std::ranges to avoid such pointers-to-
> > > > functions.
> > > > >
> > > > > template <typename T>
> > > > > struct _Impl_construct
> > > > > template <typename... Args>
> > > > > static T operator()(Args... args) { return
> > > > > T(std::forward<Args>(args)...); }
> > > > > };
> > > > >
> > > > > template <typename T>
> > > > > inline _Impl_construct construct;
> > > >
> > > > This would make taking address of std::construct not work,
> > > > which is unexpected.
> > > >
> > > > std::ranges::transform(&std::construct<T>)
> > > >
> > > >
> > > >
> > > >
> >
> >


Received on 2024-12-03 10:38:18