Date: Thu, 5 Jan 2023 01:03:36 +0300
On 1/4/23 19:41, Giuseppe D'Angelo via Std-Proposals wrote:
> Hi,
>
> Il 04/01/23 16:55, Frederick Virchanza Gotham via Std-Proposals ha scritto:
>> I could go a step further and make it work with user-defined classes;
>> in order to get this to work there would have to be a global container
>> containing elements of type pair<
>> type_info*,function<void(ostream&,void*)> > -- and for this to work
>> properly in multithreaded programs then either:
>> (a) The container must be populated from the main thread before
>> any other thread is spawned
>> (b) Protect the container with a mutex
>
>
> This sounds complicated and does not really sound suitable for
> standardization -- which container? protected under which circumstances?
> who populates it? who destroys it?
>
> This would inevitably end up in ad-hoc client code, which sounds
> possible today as you've shown (you can't just call it
> operator<<(ostream, any)).
>
> But why a repository? Can't this be achieved by extending `any` so that
> not only it type-erases a ostream streaming function, if one "exists",
> in addition to destruction/copy/move?
>
> Yes, then: why stopping there, and not also having `any` store
> type-erased versions of sizeof(T), alignof(T), operator==(T, T), "how to
> serialize T into JSON"?
The more operations you want to support, the more significant the impact
on the resulting code size and compile times. Even if you never call the
operator<< in your program that uses std::any, the compiler still has to
generate the implementation for it - for every type that you ever store
in std::any. Eventually this makes std::any too expensive to use for
more and more people.
My answer to this is one should not be using std::any in the first place
because it is a wrong tool for the job. If you have a limited set of
types known at compile time then std::variant+std::visit is a better
choice. Otherwise use the interface/implementation pattern.
Doing a runtime dispatch using std::any_cast (or even extending
std::visit to support std::any through std::any_cast dispatch) is
possible but not better than using std::variant in the first place
because you will still be limited to a number of types in compile time.
> Hi,
>
> Il 04/01/23 16:55, Frederick Virchanza Gotham via Std-Proposals ha scritto:
>> I could go a step further and make it work with user-defined classes;
>> in order to get this to work there would have to be a global container
>> containing elements of type pair<
>> type_info*,function<void(ostream&,void*)> > -- and for this to work
>> properly in multithreaded programs then either:
>> (a) The container must be populated from the main thread before
>> any other thread is spawned
>> (b) Protect the container with a mutex
>
>
> This sounds complicated and does not really sound suitable for
> standardization -- which container? protected under which circumstances?
> who populates it? who destroys it?
>
> This would inevitably end up in ad-hoc client code, which sounds
> possible today as you've shown (you can't just call it
> operator<<(ostream, any)).
>
> But why a repository? Can't this be achieved by extending `any` so that
> not only it type-erases a ostream streaming function, if one "exists",
> in addition to destruction/copy/move?
>
> Yes, then: why stopping there, and not also having `any` store
> type-erased versions of sizeof(T), alignof(T), operator==(T, T), "how to
> serialize T into JSON"?
The more operations you want to support, the more significant the impact
on the resulting code size and compile times. Even if you never call the
operator<< in your program that uses std::any, the compiler still has to
generate the implementation for it - for every type that you ever store
in std::any. Eventually this makes std::any too expensive to use for
more and more people.
My answer to this is one should not be using std::any in the first place
because it is a wrong tool for the job. If you have a limited set of
types known at compile time then std::variant+std::visit is a better
choice. Otherwise use the interface/implementation pattern.
Doing a runtime dispatch using std::any_cast (or even extending
std::visit to support std::any through std::any_cast dispatch) is
possible but not better than using std::variant in the first place
because you will still be limited to a number of types in compile time.
Received on 2023-01-04 22:04:01