On Mon, Apr 15, 2024 at 6:01 PM Thiago Macieira via Std-Proposals <std-proposals@lists.isocpp.org> 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.