C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Fwd: Extension to runtime polymorphism proposed

From: Muneem <itfllow123_at_[hidden]>
Date: Tue, 7 Apr 2026 16:47:50 +0500
Small correction in my last email:
The compiler can do one of those, the second the value itself is changed
inside the list.
Instead:
The compiler can do one of those, the second the value itself is changed
inside the list and the element itself is used


On Tue, 7 Apr 2026, 4:15 pm Muneem, <itfllow123_at_[hidden]> wrote:

> I want to make one detail clear before going to sleep:
> An object X if type type_set(selector) stores the object assigned to it.
> The way the compiler store it is implementation defined:
> 1. The compiler can use a union, which case you have that advantage of the
> feature "potential merging multiple branches" that I talked about in my
> previous email.
> 2. The compiler can cause a function call after each definition
> 3. The compiler can do one of those, the second the value itself is
> changed inside the list.
> 4. will never do one of those if the list is filled only with const
> qualified types ( don't know if it's a good idea yet).
> 5.Again, in usage it will decay into T^, which can turn into at T& or T&&,
> so you can copy or move from it.
>
>
> On Tue, 7 Apr 2026, 3:23 pm Muneem, <itfllow123_at_[hidden]> wrote:
>
>> My response to Mr.Sebistian:
>> >A) You can get a single tuple element:
>> The Dispatch instance represents it. Just use and pass the Dispatch
>> instance. Even to non-member functions.
>> You can copy/move it as you see fit.
>> >The provided index optionally is provided at runtime.
>> ****Answer****
>> 1. Passing a dispatch to a function func() would mean that the tuple
>> itself has to be in some other stack(the function that called func()),
>> hence it can't be accessed from the stack of func() which again can be
>> inefficient, since you have to go to the other function's stack location to
>> get that tuple.
>> 2. You can't copy or move, like how am I copying or moving other than
>> this dispatcher that holds a reference to a tuple and integer?
>> (For the record) the dispatch of Mr.Sebistian that I am addressing is:
>> class Dispatch
>> {
>> public:
>> Dispatch(tuple<A, B, C> t, int index);
>> void op1();
>> void op2();
>> tuple<A, B, C>& _tupleref;
>> int _index;
>> }
>>
>>
>>
>>
>>
>>
>> >B) In some emails you kept open the possibility of customizing
>> operators, of providing wrappers.
>> Now you write that is not needed, it is about calling operators with the
>> same name from unrelated (no inheritance) types.
>> >That could be a singled out feature one could follow up.
>>
>> >Currently that is possible with templates at compile-time, but not with
>> automatic code generation.
>> ****Answer****
>> 1. That won't need wrappers, it would just lead to instantiation of
>> type_set(select) into many T^'s in that type_set, so what are wrappers
>> needed for, like I never talked about wrappers, so can you please remind me
>> where did I use the term wrapper? If I did then I fully redact it since you
>> don't need wrappers because the instantiation will take care of it.
>>
>>
>>
>>
>>
>>
>> >C) The different return type, which is only known at runtime is an issue
>> in a strongly typed language. You have not solved it either.
>> If that is the center topic of your proposal, then this evaded me. The
>> template mechanism only works at compile-time.
>> >The non obvious solution is to type erase the return type.
>> >Store it on the heap or even lazily wait to actually invoke the
>> operation.
>> >Another option is to make a template out of the calling function. So you
>> have different callers for each possible type. You just kick the bucket
>> further and further up the call chain.
>> >The obvious solution would be to either return a std::variant or make
>> sure (wrapper or requirement) that the ops return the same type for each
>> element they are invoked on.
>> ****ANSWER***
>> 1.I have fixed the multiple return type problem:
>> Type_set(selector) x= selector(runtime index);
>> That is essentially the main goal of Type_set(selector) , and this is
>> still string types because the compiler does runtime checks to make sure
>> the source is one of the T^'s in Type_set(selector) .
>> 2. What I meant is that we have the template mechanism for code
>> generation, all we need is whenever a Type_set(selector) object is used,
>> then branch for each T^ in Type_set(selector) using the branching mechanism
>> that we have. The code between many instantiations can be merged if
>> selector(runtime index) is stored in a variable), which is done
>> instantiated into T^ multiple times.
>> 3. The issue with type erasure is that then what's the point of a
>> strongly typed language, if I have to at some type bypass the type system?
>> 4. This construct would take advantage of the template facilities that
>> compilers support, to implement this the compiler implementation would just
>> to use both the template instantiation and branching mechanisms they
>> already have together.
>> 5. Variants won't work because how will you use that result the next time
>> with an element of the tuple of that dispatch class?
>> You may say:
>> Provide an overload that accepts a variant?
>> Well, then we have the same issue in the visit() function of that
>> overload:
>> How will the visit return multiple types?
>> You may again say return a variant. This however makes it hard for a
>> compiler to merge the branches in:
>> B.dispatch(runtime index, std::plus, A.dispatch(runtime index, std::plus,
>> int{2}));
>> While in my case it's easier to merge them:
>> Type_set(selector) x= selector(runtime index)
>> Type_set(selector2) y= selector2(runtime index)
>> x+y+2; the compiler can flatten the two branches into one jump table of
>> N*M is small enough, where N is the amount of types in selector and M is
>> the amount of types in selector2. Basically the compiler can turn the
>> indexes of both for one 8 bit index into a jump table of N*M entries. It
>> would probably go like this (N left shit 4) +M. This as you can expect is
>> efficient and one of the main optimization selling points.
>>
>>
>>
>> D) I have not understood your argument about merging switches. When is it
>> possible, when not?
>> ****ANSWER****
>> It's only possible if you assign a function result for which all possible
>> overloads(in case the function took a selector(runtime index)), for any
>> function that returns an object type is in type_set(selector), or an index
>> from a heterogeneous list and all of the types in that list are a subset of
>> all of the type in "selector", to any variable of type type_set(selector) X.
>> When ever that variable is used, it's instantiated into T^ for the code
>> generated for all T^'s, which leads to branching, but the compiler can
>> merge the code in between multiple branches so that there is only one
>> branch needed.
>>
>>
>> On Tue, 7 Apr 2026, 2:26 pm Sebastian Wittmeier via Std-Proposals, <
>> std-proposals_at_[hidden]> wrote:
>>
>>> A) You can get a single tuple element:
>>>
>>>
>>>
>>> The Dispatch instance represents it. Just use and pass the Dispatch
>>> instance. Even to non-member functions.
>>>
>>>
>>>
>>> You can copy/move it as you see fit.
>>>
>>>
>>>
>>> The provided index optionally is provided at runtime.
>>>
>>>
>>>
>>> B) In some emails you kept open the possibility of customizing
>>> operators, of providing wrappers.
>>>
>>>
>>>
>>> Now you write that is not needed, it is about calling operators with the
>>> same name from unrelated (no inheritance) types.
>>>
>>>
>>>
>>> That could be a singled out feature one could follow up.
>>>
>>> Currently that is possible with templates at compile-time, but not with
>>> automatic code generation.
>>>
>>>
>>>
>>> C) The different return type, which is only known at runtime is an issue
>>> in a strongly typed language. You have not solved it either.
>>>
>>>
>>>
>>> If that is the center topic of your proposal, then this evaded me. The
>>> template mechanism only works at compile-time.
>>>
>>>
>>>
>>> The obvious solution would be to either return a std::variant or make
>>> sure (wrapper or requirement) that the ops return the same type for each
>>> element they are invoked on.
>>>
>>>
>>>
>>> The non obvious solution is to type erase the return type.
>>>
>>> Store it on the heap or even lazily wait to actually invoke the
>>> operation.
>>>
>>>
>>>
>>> Another option is to make a template out of the calling function. So you
>>> have different callers for each possible type. You just kick the bucket
>>> further and further up the call chain.
>>>
>>>
>>>
>>> D) I have not understood your argument about merging switches. When is
>>> it possible, when not?
>>>
>>>
>>>
>>>
>>>
>>>
>>> -----Ursprüngliche Nachricht-----
>>> *Von:* Muneem via Std-Proposals <std-proposals_at_[hidden]>
>>> *Gesendet:* Di 07.04.2026 10:58
>>> *Betreff:* Re: [std-proposals] Fwd: Extension to runtime polymorphism
>>> proposed
>>> *An:* std-proposals_at_[hidden];
>>> *CC:* Muneem <itfllow123_at_[hidden]>;
>>> My response to Mr.sebistian's welcomed and appreciaed feedback
>>>
>>> >The Dispatch type would know/store all the information like the index
>>> and the tuple element types as runtime or compile time information. The
>>> optimizer can inline the usage of the type, so it never actually exists in
>>> memory.
>>> It works with current and former C++ versions.
>>> ****ANSWER****
>>> 1The dispatch technique that you described in your previous emails has
>>> the problems :
>>> 1. You can't get a value out of the underlying tuple, which might not
>>> matter to you, but it is a fundamental aspect of a list/container.
>>> 2. For a tuple of built in types, you have to provide an op for each
>>> operator, which as you can expect be lengthy.
>>> 3. Even if you make it short for built in types by allowing to accept a
>>> function objects for dispatch function, even then you can't provide
>>> different return types for different dispatches, so basically, if adding an
>>> int to a float element of a tuple returns float, then adding a int to a int
>>> also has to return float.
>>> 4. The issue with return types in point 3 apply to all types
>>> 5. You cant pass an element of the tuple to a non member function.
>>> 6. the compiler does not have a free hand of merging switches because it
>>> can assume whether the index is the same or not, while in my case you can
>>> assign a value from an index to a type_set(selector), and the compiler has
>>> a freehand to merge the branching when ever it feels like it should. For
>>> that type_set(selector) X variable.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> >The more new constructs, value types and syntax you add, the higher the
>>> bar for your proposal.
>>>
>>> ****ANSWER****
>>> 1. The issues with not adding things is that then it dosent actually
>>> become useful.
>>> 2.Without extra constructs and value types, you can't fix the issue of
>>> needing different return types of the same dispatch based on the index.
>>> This issue was the main issue that I even proposed a proposal in the first
>>> place, so I don't want to fix the problem incompletely.
>>> 3. Modifying std::variants(if by any chance you are thinking about that)
>>> to work for heterogeneous lists in a type safe manner (the type safety that
>>> I previously talked about of having fixed types at fixed indexes) would
>>> still rely on adding new types under the hood.
>>> 3. Modifying tuples(to make the dispatch mechanism pivot for a use case
>>> if heterogeneous lists) or unions/variant is worse since we are adding into
>>> fundamental notions, that could break the principle "zero cost abstraction".
>>>
>>>
>>>
>>>
>>>
>>> >See the T^ as a Dispatch object.
>>> What is possible with T^, which Dispatch cannot do?
>>> ****ANSWER****
>>> 1.Dispatch object is type_set(selector), but it instantiates into T^
>>> whenever used.
>>> 2. T^ is just to make it more type safe, for example, the programmer may
>>> be handling a http packet, and some parts of that packet are not to be
>>> accessed through the heterogeneous list because the list can be indexed by
>>> value provided by the user. So the programmer, makes overloads for T^, so
>>> the user can only use an object of a particular T^ if he is authorized
>>> and/or authentication. This is just an example, but enough to tell, that
>>> with great power comes responsibility, which means that to avoid
>>> vulnerabilities of allowing any type of object to be indexed to backfire,
>>> this would help protect from it. You may disagree for the need of T^ but
>>> again considering that heterogeneous lists will mostly be ever used in
>>> networking protocols, JSONs, XMLs, you want as the programmer to have a
>>> freehand in providing (application) safety, when you let a user index your
>>> list with any index he wants. This is better than checking for the
>>> potentially hazardous indexes because that's slower and verbose.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> >Why do you think, Dispatch needs switch?
>>>
>>>
>>> >And even if it uses switch, why do you think this is bad? Verbosity of
>>> source code? Then let's discuss, how to write Dispatch in a short way.
>>> Performance? Even if switch is used, why do you think the optimizer won't
>>> change it to jump tables? We still have the index and the complete
>>> information available, same as T^.
>>> ****ANSWER****
>>> 1. The first issue with switch case statements in this case is as I said
>>> merging.
>>> 2. Verbosity of source is an issue but not the only issue, so even if
>>> you make it short, the first point instrusively makes it worse.
>>>
>>>
>>> >That is the trick with C++: You can create abstractions, which are
>>> simple enough for the optimizer to remove again.
>>>
>>>
>>>
>>> >Compare it to unique_ptr. In most cases, unique_ptr just simplifies to
>>> a raw pointer in assembly.
>>>
>>> ***ANSWER***
>>> 1.The index is runtime, and you can't assign it to an variable so no,
>>> it's not easy, since the index can be anything at runtime, and to access
>>> the value, you need to use dispatch, you can't copy/move the element
>>> outside and use it outside.
>>> 2. Pointers are different since the "dispatch" they have to do in
>>> concept is mostly just a hardware instruction, no new semantics around it
>>> other than the old semantics of a built in pointer.
>>>
>>>
>>> But I don't want to hype my solution, but give you the possibility to
>>> either show differences to better see, what your proposal has to offer. And
>>> to give you a way to either abandon or radically simplify your proposal.
>>> ***ANSWER***
>>> I know, but as explained by my answers to your previous questions, your
>>> proposal dosent solve all problems, and to actually solve all problems, and
>>> to solve it in a way that an application program can still be safe, you
>>> need two value types along thing construct. One for branching, and the
>>> other(T^) for the former to branch into, and the applications programmer to
>>> provide code for, in case he thinks that the user giving input is not trust
>>> worthy to access certain types unless he has a authorized/authenticated to
>>> do so.
>>>
>>>
>>>
>>> >Currently you want to introduce customization points (wrappers), new
>>> interfaces (between non-related classes), a new value category, which needs
>>> codegen wherever it is used, together with new basic syntax. Not even
>>> talking about JIT.
>>> ****ANSWER****
>>> 1. No I don't have to introduce customization points, no new interfaces.
>>> 2. Just that all classes in the list must have the same members, and all
>>> functions called on either one of them shall exist for all of them. The
>>> other new things is a new expression value type "type_set(selector) and a
>>> T^ that the former instnatied into, and at last an implementation defined
>>> container for type_set(selector) to be the heterogeneous list.
>>> 3. We don't need a JIT, template mechanisms already exist, all we need
>>> is branching which again already exist, and there are many ways that the
>>> compiler can choose from:
>>> 1. Normal branching using conditional jumps.
>>> 2. Vtable dispatch or functions called by each block that the normal
>>> branch jumps to.
>>> 3.jump tables
>>> The compiler can choose them for each instantion and merge them for the
>>> code between each instantion. Basically the compiler have freehand. This is
>>> for me like AI code generation, but better.
>>>
>>> >The more needed elements you add, I am talking about elements, which
>>> don't build on existing C++, the more you build a different language.
>>> Currently I get the feeling your changes to the language go beyond the
>>> current reflection+meta-programming without equal new possibilities and
>>> without equal need.
>>> ****ANSWER****
>>> 1. Was defining rvalues defining a new language, the answer is yes and
>>> no:
>>> 1. No because: Rvalues fit the current Grammer structure of c++, didn't
>>> break existing code unless the user provided overloads for rvalues.
>>> 2. Yes because: it made c++ feel different.
>>> 3. Yes it does go beyond meta programming because it extends it. You
>>> could say that the need of it isn't there, but did anyone ask for rvalues,
>>> space ship operator's, or other automation facilities? Why didn't they?
>>> Because other compiled languages didn't have them yet.
>>> Just because c++ is the first to have them, dosent mean it should not
>>> have them.
>>>
>>>
>>> On Tue, 7 Apr 2026, 12:10 pm Sebastian Wittmeier via Std-Proposals, <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>> The Dispatch type would know/store all the information like the index
>>> and the tuple element types as runtime or compile time information. The
>>> optimizer can inline the usage of the type, so it never actually exists in
>>> memory.
>>>
>>>
>>>
>>> It works with current and former C++ versions.
>>>
>>>
>>>
>>> The more new constructs, value types and syntax you add, the higher the
>>> bar for your proposal.
>>>
>>>
>>>
>>>
>>>
>>> See the T^ as a Dispatch object.
>>>
>>>
>>>
>>> What is possible with T^, which Dispatch cannot do?
>>>
>>>
>>>
>>>
>>>
>>> Why do you think, Dispatch needs switch?
>>>
>>> And even if it uses switch, why do you think this is bad? Verbosity of
>>> source code? Then let's discuss, how to write Dispatch in a short way.
>>> Performance? Even if switch is used, why do you think the optimizer won't
>>> change it to jump tables? We still have the index and the complete
>>> information available, same as T^.
>>>
>>> That is the trick with C++: You can create abstractions, which are
>>> simple enough for the optimizer to remove again.
>>>
>>>
>>>
>>> Compare it to unique_ptr. In most cases, unique_ptr just simplifies to a
>>> raw pointer in assembly.
>>>
>>>
>>>
>>> But I don't want to hype my solution, but give you the possibility to
>>> either show differences to better see, what your proposal has to offer. And
>>> to give you a way to either abandon or radically simplify your proposal.
>>>
>>>
>>>
>>> Currently you want to introduce customization points (wrappers), new
>>> interfaces (between non-related classes), a new value category, which needs
>>> codegen wherever it is used, together with new basic syntax. Not even
>>> talking about JIT.
>>>
>>>
>>>
>>> The more needed elements you add, I am talking about elements, which
>>> don't build on existing C++, the more you build a different language.
>>> Currently I get the feeling your changes to the language go beyond the
>>> current reflection+meta-programming without equal new possibilities and
>>> without equal need.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> -----Ursprüngliche Nachricht-----
>>> *Von:* Muneem via Std-Proposals <std-proposals_at_[hidden]>
>>> *Gesendet:* Di 07.04.2026 03:08
>>> *Betreff:* Re: [std-proposals] Fwd: Extension to runtime polymorphism
>>> proposed
>>> *An:* std-proposals_at_[hidden];
>>> *CC:* Muneem <itfllow123_at_[hidden]>;
>>> My response to Mr.Sebistian.
>>> (Note: I use T^ just as an example of the name, the real name would
>>> again be up to you guys because I can't make a judgment on syntax with
>>> limited experience)
>>> >To keep it simple and stay at the problem once again:
>>>
>>>
>>>
>>> >From a std::tuple<T, U, V>
>>>
>>> >you want to select an element by index (possibly runtime)
>>>
>>> >it returns something like std::variant<T, U, V>, but perhaps with
>>>
>>> - better support of references
>>>
>>> - storing the index used for selection
>>>
>>> - custom operation wrappers
>>>
>>>
>>>
>>> >That std::variant like type allows (common) operations to be called on.
>>>
>>>
>>>
>>>
>>>
>>> >In current C++ I would create a class (UR is a custom class, not inside
>>> the standard library):
>>>
>>>
>>>
>>>
>>>
>>> class Dispatch
>>>
>>> {
>>>
>>> public:
>>>
>>> Dispatch(tuple<A, B, C> t, int index);
>>>
>>>
>>>
>>> void op1();
>>>
>>> void op2();
>>>
>>>
>>>
>>> tuple<A, B, C>& _tupleref;
>>>
>>> int _index;
>>>
>>> }
>>>
>>>
>>>
>>> >Then the compiler has anything it needs for optimization. What is
>>> missing compared to your solution?
>>>
>>>
>>>
>>>
>>>
>>> tuple<A, B, C> t = { a, b, c }; // initialize
>>>
>>> Dispatch<A, B, C> d(t, i); // select index i
>>>
>>> i.op2(); // call operations
>>>
>>>
>>>
>>>
>>>
>>> >No need for new categories or value types or new syntax?
>>>
>>> >Full flexibility for customization.
>>>
>>> >Full optimization potential.
>>> ****ANSWER****
>>> 1. As I said the new T^ would allow for the user to see elements of type
>>> T in heterogeneous list coming.
>>> 2. I updated my proposal (in my last email to Mr.thiago) to have a new
>>> type other T^, that is different (and more type safe) than std::variant.
>>> ****Limitations in your example****
>>> 1. I can't pass an element from the tuple in your example to a function,
>>> and expect an instantion from type_set(selector) to T^(as in my case) which
>>> can further decay into T or T& or T&&. This is important because without
>>> this feature your elements in tuple are stuck, and can be passed to a
>>> function based on runtime indexes without switch statements that I am
>>> guessing dispatch already has to use.
>>> 2. Compiler can't use additional book keeping for the switch case
>>> statements that you are using in dispatch because of the zero overhead
>>> Principe limiting tuples to be tuples instead of runtime indexed
>>> heterogeneous lists.
>>> 3. You cant assign/move to the element that
>>> d.index is pointing to. While in my case you can (refer to my last
>>> response to Mr. Thiago:
>>> https://lists.isocpp.org/std-proposals/2026/04/17675.php), to see the
>>> additional expression value type that I proposed.
>>>
>>>
>>>
>>> On Mon, 6 Apr 2026, 4:04 pm Sebastian Wittmeier via Std-Proposals, <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>> To keep it simple and stay at the problem once again:
>>>
>>>
>>>
>>> From a std::tuple<T, U, V>
>>>
>>> you want to select an element by index (possibly runtime)
>>>
>>> it returns something like std::variant<T, U, V>, but perhaps with
>>>
>>> - better support of references
>>>
>>> - storing the index used for selection
>>>
>>> - custom operation wrappers
>>>
>>>
>>>
>>> That std::variant like type allows (common) operations to be called on.
>>>
>>>
>>>
>>>
>>>
>>> In current C++ I would create a class (UR is a custom class, not inside
>>> the standard library):
>>>
>>>
>>>
>>>
>>>
>>> class Dispatch
>>>
>>> {
>>>
>>> public:
>>>
>>> Dispatch(tuple<A, B, C> t, int index);
>>>
>>>
>>>
>>> void op1();
>>>
>>> void op2();
>>>
>>>
>>>
>>> tuple<A, B, C>& _tupleref;
>>>
>>> int _index;
>>>
>>> }
>>>
>>>
>>>
>>> Then the compiler has anything it needs for optimization. What is
>>> missing compared to your solution?
>>>
>>>
>>>
>>>
>>>
>>> tuple<A, B, C> t = { a, b, c }; // initialize
>>>
>>> Dispatch<A, B, C> d(t, i); // select index i
>>>
>>> i.op2(); // call operations
>>>
>>>
>>>
>>>
>>>
>>> No need for new categories or value types or new syntax?
>>>
>>> Full flexibility for customization.
>>>
>>> Full optimization potential.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> -----Ursprüngliche Nachricht-----
>>> *Von:* Muneem via Std-Proposals <std-proposals_at_[hidden]>
>>> *Gesendet:* Mo 06.04.2026 03:35
>>> *Betreff:* Re: [std-proposals] Fwd: Extension to runtime polymorphism
>>> proposed
>>> *An:* std-proposals_at_[hidden];
>>> *CC:* Muneem <itfllow123_at_[hidden]>;
>>> My answer to Mr.Thiago Marciena
>>>
>>> >So far, all I've understood is that this is a new syntax for
>>> simplifying:
>>> a) the creation of a std::variant<references, ...>
>>> b) visitation
>>>
>>> That is, if you had:
>>> std::vector<Foo>
>>> std::map<Foo, Bar>
>>>
>>> You would implicitly declare a
>>> std::variant<std::vector<Foo> &, std::map<Foo, Bar> &>
>>>
>>> populate it with either a runtime or compile time choice
>>>
>>> and visit it, calling a function or more in it.
>>>
>>> It would be up to the compiler to determine that every use of this type
>>> compiles for every type in the variant.
>>>
>>> ****answer****
>>> You are mostly right but with some major details left out:
>>> 1.the user can overload based of the new expression value type, which
>>> allows the user to reason better.
>>> 2. This new type can be passed to functions and the compiler will
>>> instantiate each function that was found in the overload resolution of each
>>> type for this. Which might sound like std::visit but is much more different:
>>> 1.for a compile time index, the compiler gurrenties inlining.
>>> 2. The compiler gurrenties that returning a heterogeneous set only leads
>>> to a pointer move (mechanism is just like exceptions can be captured using
>>> references for performance).
>>> 3. Unlike std::array or vectors of std::variants, the representation of
>>> this list would be completely up to the compiler, hence the code instnatied
>>> for each one would be as well.
>>> 4. Std::visit can only return a variant, while In my case, for any
>>> func() that you pass an element of the heterogeneous list to, the overload
>>> of func() chosen for each possible type(of elements in the list) can return:
>>> 1.T
>>> 2. Or just that type as T^
>>> In both cases, unless the user casts the return value of func to
>>> specific value T or T^, you can only assign the return value of func tons
>>> variable if the variable is variant, unless the index is constexpr, in
>>> which case you can assign it to T and the compiler will make sure you get
>>> an error unless the type is correct. If any of the functions return T, then
>>> the ones returning T^ would be decayed into T or conversely, we could tell
>>> the compiler to throw an error (upto comcencess). Std::variants can further
>>> enchance this by allowing the usage of variants of type T^, for each
>>> std::variant<T^, U^, V^>, this could help function overloads see
>>> heterogeneous element accesses coming and handle them. T^ for any T is
>>> gurrentied to be the size of a simple pointer.
>>>
>>>
>>> >I don't see how you're solving this problem. There are two issues that
>>> cause
>>> object slicing: first, it's the calling of a function to implement it.
>>> This is
>>> easy to do with a virtual function, so a solved problem, but different
>>> from
>>> copy/move semantics.
>>>
>>> ***Answer***
>>> Problem isn't solved using virtual functions, for example:
>>> Base *ptr= new Base{};
>>> Dereieved obj;
>>> Obj= virtual_clone(ptr);
>>> //Slicing so problem is not solved
>>>
>>>
>>> >Second and most importantly: the destination memory area must be of
>>> sufficient
>>> size to accommodate any of the runtime full objects, which by definition
>>> cannot
>>> be known at compile time. You are not addressing this problem. And if
>>> you come
>>> up with a solution for it, then it is also available for the case of
>>> calling a
>>> virtual function.
>>>
>>> ***Answer***
>>> The destination in this case would either be std::variant or T(if index
>>> is constexpr or a explicit cast specifically for this job is created). The
>>> specific cast job would also be of a massive help to implement this.
>>>
>>>
>>> >And again: what do virtual functions and object slicing have to do with
>>> anything?
>>>
>>> ***Answer***
>>> Because it shows virtual functions are incomplete, say you have want a
>>> list of integers, floats, doubles, and you want to do arithmetic, now you
>>> have to use either wrap each in variant, in which case you want pass them
>>> to overloads expecting this specific case. The compiler isn't given a free
>>> hand for the list representation, but rather wrapped in the constraints of
>>> a pre existing container that provides gurrenties that pivoted to other
>>> motivations. In Mr. Steve's case, it was arrays holding "wrapper clases" to
>>> multiple different container type objects. In my case it would be probably
>>> very similar to what I talked about in here:
>>> https://lists.isocpp.org/std-proposals/2026/04/17641.php.
>>>
>>>
>>> >Same as std::variant then.
>>> ***ANSWER***
>>> Not the same as variant for the reasons that talked about in the
>>> paragraph above. Basically a new heterogeneous list would be pivoted
>>> towards representation thats best for itself rather than being in the
>>> constraints of the gurrentied behaviours of some other container. Though
>>> there would be no dynamic allocating what so ever.
>>>
>>> >And I don't see how you're solving this problem. This is still the
>>> "magic
>>> happens" portion of what you've been trying to convey for a week and it
>>> seems
>>> no one understands.
>>>
>>> You seem to be saying that one needs to have an overload for each of the
>>> possible types, but your solution removes this need. How?
>>> ***Answer***
>>> The magic portion is that you can provide overloads specifically for
>>> these value types T^ that see elements of heterogeneous coming. A even
>>> better one would be functions accepting std::variants of these T^ or T
>>> types. So the solution to the magic exists, but to take advantage of it, we
>>> need that solution to not be constraint by the gurrentied behaviours of
>>> current container(in order to make them into lists), and to see the
>>> elements of those heterogeneous coming so we can provide overloads for them.
>>>
>>> >We don't know if it is type-safe, because we can't tell what the type
>>> is and
>>> how the compiler can reason anything at compile time to prove safety,
>>> because
>>> we don't understand what you're proposing.
>>> ***Answer***
>>> 1. It is type safe just like std::visit in that everything is produced
>>> at compile time, but also not like solutions based of std::visits:
>>> 1. it's not constraint by containers meant used with std::variants.
>>> 2. provides more gurrenties like the one I talked about here:
>>> https://lists.isocpp.org/std-proposals/2026/04/17641.php.
>>> 3.unlike an array of variants, each element has a fixed type, so you
>>> can't change it. This makes it more type safe and contained, which also
>>> makes it easy to optimize, and provide gurrentied for (constexpr indexes).
>>> 4. Because each index has a fixed type, the compiler can further
>>> optimize for that aspect.
>>>
>>>
>>> Basically think of it as the better of both variants and tuples.
>>>
>>>
>>>
>>>
>>>
>>> Regards, Muneem
>>>
>>> On Mon, 6 Apr 2026, 4:51 am Thiago Macieira via Std-Proposals, <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>> On Sunday, 5 April 2026 10:49:34 Pacific Daylight Time Steve Weinrich
>>> via Std-
>>> Proposals wrote:
>>> > He seems to be fixated on a container of some type that returns
>>> references
>>> > to different type of containers. For the life of me, I can't figure
>>> out why
>>> > this would be needed or how to make it type-safe!
>>>
>>> So far, all I've understood is that this is a new syntax for simplifying:
>>> a) the creation of a std::variant<references, ...>
>>> b) visitation
>>>
>>> That is, if you had:
>>> std::vector<Foo>
>>> std::map<Foo, Bar>
>>>
>>> You would implicitly declare a
>>> std::variant<std::vector<Foo> &, std::map<Foo, Bar> &>
>>>
>>> populate it with either a runtime or compile time choice
>>>
>>> and visit it, calling a function or more in it.
>>>
>>> It would be up to the compiler to determine that every use of this type
>>> compiles for every type in the variant.
>>>
>>> --
>>> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>>> Principal Engineer - Intel Data Center - Platform & Sys. Eng.
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>>> -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>>> To keep
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>>> -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>>> --
>>> Std-Proposals mailing list
>>> Std-Proposals_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>
>>

Received on 2026-04-07 11:48:09