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:15:55 +0500
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:16:14