Date: Tue, 16 Apr 2024 13:38:51 +0300
On Mon, Apr 15, 2024 at 6:01 PM Thiago Macieira via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> On Monday 15 April 2024 00:45:17 GMT-7 Mihail Mihaylov via Std-Proposals
> wrote:
> > The base class can be polymorphic, while the derived class can be final
> and
> > copyable. Consider a base abstract interface class which has multiple
> final
> > copyable implementation classes. The "sender" can store into the `any` an
> > instance of the copyable derived type and the receiver could extract a
> base
> > pointer or base reference to the contained value.
>
> What are sender and receiver here?
>
The sender is any code which stores a value in the any object. The receiver
is any code which extracts the value from the any object or a pointer to
the value.
> Since you didn't specify and it wasn't part of the discussion, I'm going
> to
> assume it refers to Qt signals.
I gave a code example. I believe that there are tons of code that follow
the pattern demonstrated by this example. I don't think that this
Qt-specific scenario is relevant.
> In that case, this use-case doesn't make
> sense: you identify the sender by its pointer address, not by a copy of
> it.
> QObect are not copyable so they can't be put inside of a std::any.
>
> A pointer to a QObject can. But then the solution is simple: you store the
> pointer to the QObject and allow dynamic_casting or qobject_casting to the
> user's desired type to see if it is such or not.
>
The discussion is not about storing pointers in the any. It is about
storing an object which is owned by the any.
> This is very common when we are using non-erased types, so I believe it's
> > perfectly reasonable to want it with erased types too. And the only
> reason
> > Jason had me convinced for a moment that this is not reasonable for
> > `std::any` specifically, is because he made me believe that `any_cast`
> > always copies the value, which is not true.
>
> I do not. This use-case is already solved by a pointer to the base class.
> I
> don't see why std::any needs to support the casting if you can simply use
> the
> pointer itself. And I definitely don't see why you should need to store
> the
> full object inside of std::any.
>
I already addressed the "base class" argument. If you are dealing with
objects that have a common base, then definitely use a Base* or
unique_ptr<Base> or shared_ptr<Base> or polymorphic_value<Base>. But with
disjoint types we need a union type and that's when we use any. And if one
of the disjoint types that we store in the any has descendents, we have the
use case that's under discussion here.
> > Please, note that in the example above, we are not storing a pointer, we
> > are storing a `Derived` value, and `std::any` allows us to extract a
> > `Derived *` to it. What we want is to be able to extract a `Base *`
> pointer
> > to it. Also note that `foo(Base*)` doesn't need to know about `Derived`
> for
> > it to be used with a `Derived` instance, and similarly, we would like for
> > `foo(any *)` to be able to handle an `any` that contains a `Derived`
> > instance while knowing only about `Base`.
> >
> > In other words, my argument is that `any_cast<Base>(any *)` should be on
> > par with `static_cast<Base*>(Derived *)`.
>
> I understand. I just don't agree that this is a justified use-case.
>
I don't see how we can resolve this difference in opinion in this
discussion.
std-proposals_at_[hidden]> wrote:
> On Monday 15 April 2024 00:45:17 GMT-7 Mihail Mihaylov via Std-Proposals
> wrote:
> > The base class can be polymorphic, while the derived class can be final
> and
> > copyable. Consider a base abstract interface class which has multiple
> final
> > copyable implementation classes. The "sender" can store into the `any` an
> > instance of the copyable derived type and the receiver could extract a
> base
> > pointer or base reference to the contained value.
>
> What are sender and receiver here?
>
The sender is any code which stores a value in the any object. The receiver
is any code which extracts the value from the any object or a pointer to
the value.
> Since you didn't specify and it wasn't part of the discussion, I'm going
> to
> assume it refers to Qt signals.
I gave a code example. I believe that there are tons of code that follow
the pattern demonstrated by this example. I don't think that this
Qt-specific scenario is relevant.
> In that case, this use-case doesn't make
> sense: you identify the sender by its pointer address, not by a copy of
> it.
> QObect are not copyable so they can't be put inside of a std::any.
>
> A pointer to a QObject can. But then the solution is simple: you store the
> pointer to the QObject and allow dynamic_casting or qobject_casting to the
> user's desired type to see if it is such or not.
>
The discussion is not about storing pointers in the any. It is about
storing an object which is owned by the any.
> This is very common when we are using non-erased types, so I believe it's
> > perfectly reasonable to want it with erased types too. And the only
> reason
> > Jason had me convinced for a moment that this is not reasonable for
> > `std::any` specifically, is because he made me believe that `any_cast`
> > always copies the value, which is not true.
>
> I do not. This use-case is already solved by a pointer to the base class.
> I
> don't see why std::any needs to support the casting if you can simply use
> the
> pointer itself. And I definitely don't see why you should need to store
> the
> full object inside of std::any.
>
I already addressed the "base class" argument. If you are dealing with
objects that have a common base, then definitely use a Base* or
unique_ptr<Base> or shared_ptr<Base> or polymorphic_value<Base>. But with
disjoint types we need a union type and that's when we use any. And if one
of the disjoint types that we store in the any has descendents, we have the
use case that's under discussion here.
> > Please, note that in the example above, we are not storing a pointer, we
> > are storing a `Derived` value, and `std::any` allows us to extract a
> > `Derived *` to it. What we want is to be able to extract a `Base *`
> pointer
> > to it. Also note that `foo(Base*)` doesn't need to know about `Derived`
> for
> > it to be used with a `Derived` instance, and similarly, we would like for
> > `foo(any *)` to be able to handle an `any` that contains a `Derived`
> > instance while knowing only about `Base`.
> >
> > In other words, my argument is that `any_cast<Base>(any *)` should be on
> > par with `static_cast<Base*>(Derived *)`.
>
> I understand. I just don't agree that this is a justified use-case.
>
I don't see how we can resolve this difference in opinion in this
discussion.
-- This electronic communication and the information and any files transmitted with it, or attached to it, are confidential and are intended solely for the use of the individual or entity to whom it is addressed and may contain information that is confidential, legally privileged, protected by privacy laws, or otherwise restricted from disclosure to anyone else. If you are not the intended recipient or the person responsible for delivering the e-mail to the intended recipient, you are hereby notified that any use, copying, distributing, dissemination, forwarding, printing, or copying of this e-mail is strictly prohibited. If you received this e-mail in error, please return the e-mail to the sender, delete it from your computer, and destroy any printed copy of it.
Received on 2024-04-16 10:39:05