Date: Tue, 3 Dec 2024 14:56:53 +0000
On Tue, 3 Dec 2024 at 14:10, Avi Kivity via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> We should have a type that pin<> (or senders/receivers) can be
> constructed from, so we can pass them along stuff like std::apply or
> the proposed std::construct.
>
If I understand Gašper's point, the concern is not about constructing a
pin<T> (or other immovable type), it's about constructing an object that
takes a pin<T> by value as a constructor argument:
struct MyType {
MyType(pin<int>);
...
};
This wants to be given a pinned int by value, which can work nicely with
C++17 guaranteed copy elision. But anything which uses perfect forwarding
to pass arguments to the MyType constructor is going to pass it a
pin<int>&& which then cannot be moved/copied into the by-value parameter.
You would need something like:
auto pin_it = []<typename T>(in_place_type_t<T>, auto&&... a) {
return pin<T>(std::forward<decltype(a)>(a)...);
};
which returns by value, and then pass that closure to
std::construct<MyType>, and have it invoke the closure to get a prvalue
that can be passed to the MyType constructor.
And then we'd want to make that generic and reusable, so you'd be able to
compose those prvalue factories:
auto x = std::construct<MyType>(std::builder<Foo>(args, for, foo), _1,
std::builder<Bar>(another, arg), xyz);
MyType m = x("str");
When invoked, this would do something like:
return MyType(Foo(args, for, foo), "str", Bar(another, arg), xyz);
i.e. creating prvalues of types Foo and Bar on the fly and passing them
directly to the MyType constructor, so there are no references and no
forwarding.
But this gets a lot more complicated than your original idea :-)
>
> On Tue, 2024-12-03 at 13:10 +0000, Gašper Ažman via Std-Proposals
> wrote:
> > pin<> is an archetype of "nonmovable" - and with sender/receiver and
> > its operation states, "nonmovable" is actually super common.
> >
> > On Tue, Dec 3, 2024 at 11:07 AM Sebastian Wittmeier via Std-Proposals
> > <std-proposals_at_[hidden]> wrote:
> > >
> > >
> > > Hi Avi,
> > >
> > > Is this a contradiction?
> > >
> > > "The problem happen anywhere you use perfect forwarding."
> > > "Just because one class is broken wrt perfect forwarding"
> > >
> > >
> > >
> > > > 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.
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
std-proposals_at_[hidden]> wrote:
> We should have a type that pin<> (or senders/receivers) can be
> constructed from, so we can pass them along stuff like std::apply or
> the proposed std::construct.
>
If I understand Gašper's point, the concern is not about constructing a
pin<T> (or other immovable type), it's about constructing an object that
takes a pin<T> by value as a constructor argument:
struct MyType {
MyType(pin<int>);
...
};
This wants to be given a pinned int by value, which can work nicely with
C++17 guaranteed copy elision. But anything which uses perfect forwarding
to pass arguments to the MyType constructor is going to pass it a
pin<int>&& which then cannot be moved/copied into the by-value parameter.
You would need something like:
auto pin_it = []<typename T>(in_place_type_t<T>, auto&&... a) {
return pin<T>(std::forward<decltype(a)>(a)...);
};
which returns by value, and then pass that closure to
std::construct<MyType>, and have it invoke the closure to get a prvalue
that can be passed to the MyType constructor.
And then we'd want to make that generic and reusable, so you'd be able to
compose those prvalue factories:
auto x = std::construct<MyType>(std::builder<Foo>(args, for, foo), _1,
std::builder<Bar>(another, arg), xyz);
MyType m = x("str");
When invoked, this would do something like:
return MyType(Foo(args, for, foo), "str", Bar(another, arg), xyz);
i.e. creating prvalues of types Foo and Bar on the fly and passing them
directly to the MyType constructor, so there are no references and no
forwarding.
But this gets a lot more complicated than your original idea :-)
>
> On Tue, 2024-12-03 at 13:10 +0000, Gašper Ažman via Std-Proposals
> wrote:
> > pin<> is an archetype of "nonmovable" - and with sender/receiver and
> > its operation states, "nonmovable" is actually super common.
> >
> > On Tue, Dec 3, 2024 at 11:07 AM Sebastian Wittmeier via Std-Proposals
> > <std-proposals_at_[hidden]> wrote:
> > >
> > >
> > > Hi Avi,
> > >
> > > Is this a contradiction?
> > >
> > > "The problem happen anywhere you use perfect forwarding."
> > > "Just because one class is broken wrt perfect forwarding"
> > >
> > >
> > >
> > > > 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.
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2024-12-03 14:58:13