C++ Logo

std-proposals

Advanced search

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

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Wed, 8 Apr 2026 03:11:30 +0200
śr., 8 kwi 2026 o 02:27 Muneem <itfllow123_at_[hidden]> napisał(a):
>
> >I do not know if you know how it will work, you again repeat nearly
> the same text without addressing the question.
> You name `T^` as an expression but you use this symbol only as a type
> of argument of template function, and this is not an expression.
> Please stop using terms that you do not know what they mean.
> Besides, why not use there normal `T&`? You break the whole overload
> resolution, drill hole in value categories for what exactly?
> Which one should be chosen: `Derived&` or `Base^` overload or opposite
> `Derivad^` or `Base&`?
> What is the difference between `T&` and `T^` on assembly level? What
> can I do with `T^` that is impossible with `T&`?
> >`type_set` is pointless, it should be same as `decltype(comtainer_obj)`
> ***ANSWER***
> 1. I NAMED T^ as in for ever T in the heterogeneous list, but sorry if I didn't convey my point properly.
> 2. The new value type T^ for every T is important because people may not be comfortable to add certain types in heterogeneous lists, like I may feel uncomfortable to add cookies in my heterogeneous lists because someone might steal them.

What on earth is arguing for "comfortable"?? I ask for technical
reasons why you need things like this and this is not the answer.

> 3. The new T^ is important because it is what type_set(selector) decays into, If I had said that type_set(selector) decays to a T lvalue or a T xvlaue then that would require some modifications to them which would break the zero overbead principle.

What modifications?

> Basically the goal was that it should be easy to implement, by making it completely separate. once instantiation is done then only can T^ mix into T&. The goal in short was to not drill a whole by mixing current expression types, but rather make a new one that every implementation can treat for this specific goal of instantion.

"easy to implement" no it isn't, adding new value category can be
effective breaking change that will affect every code as for example:

```
struct Foo
{
   void bar() &;
   void bar() &&;
};
```

Now its need `void bar() ^;` too.

> 4. You asked:
> >Which one should be chosen: `Derived&` or `Base^` overload or opposite
> `Derivad^` or `Base&`?
> Replace Base^ and derived^ with rvalue references and then you know. Basically the overload resolution is the same, it's just another value type.

No, you add a new version of it and do not answer how it interacts
with old ones. Did you ever read how complex is overload resolution in
C++?
Read it and add this `^` without breaking it:

https://en.cppreference.com/w/cpp/language/overload_resolution.html

here you have some simplified version of it (I do not know how
accurate it is to standard text but probably a good approximation)
Could you show in that text where your `T^` will fit?

> 5. T^ is not different on a assembly level, it just helps user provide overloads for it, and the compiler to instantiate type_set(selector) into it. The mechanics of T^ is implementation defined, In that how type_set(selector) instnatiates into T^ is implementation defined, why?
> The answer is that if type_set(selector) were to instantiate into something else(lvalue), the compiler might have had to modify how lvalues work. I want to keep them separate.

again, modify what exactly?

> >To recap expresion is `1` or `1 + 2` or `foo()`, something `T&` like
> in `void foo(T& a)` is some kind of type. Again please do use terms
> you know what they mean exactly otherwise you will confuse yourself
> and everyone else who is trying to read your proposal.
> ***ANSWER***
> 1. Again, I am sorry for mixing terms, but it's an expression type in a sense that when type_set(selector) object is used then it instnatiates into T^ expression type for a T. When a function takes T^ for some T then it's a object type. The semantics for T^ is the same as lvalues, it's just useful for overloads as I described earlier.
>
>
> On Tue, 7 Apr 2026, 5:29 pm Marcin Jaczewski, <marcinjaczewski86_at_[hidden]> wrote:
>>
>> wt., 7 kwi 2026 o 05:23 Muneem <itfllow123_at_[hidden]> napisał(a):
>> >
>> > My response Mr.thiago and Mr.Marcin
>> >
>> > Before my response, let me summarize my proposal in the shortest possible words:
>> > A implementation defined container type that holds an object of type "type_set(container_object)". When
>> > ever any type_set(container_object) is used for any container_object of this type, then it instantiates into T^(syntax can be something else for T^). So passing typeset to a function, will call the overload for T^, unless it isn't defined(some other is). T^ is a new expression type that's a subset glvalue, but overloads that use T^ hold a reference to that object. type_set(container_object) is a completelt new expression type, when it decays into T^, the compiler instantiates all code. You may disagree the need for T^, but I think it will help users overload and see it coming.A variable can be of type type_set(comtainer_obj), in which case the user if it will lead to instnatiation. This makes code easy to reason about and deal with.
>> >
>>
>> I do not know if you know how it will work, you again repeat nearly
>> the same text without addressing the question.
>> You name `T^` as an expression but you use this symbol only as a type
>> of argument of template function, and this is not an expression.
>> Please stop using terms that you do not know what they mean.
>> Besides, why not use there normal `T&`? You break the whole overload
>> resolution, drill hole in value categories for what exactly?
>> Which one should be chosen: `Derived&` or `Base^` overload or opposite
>> `Derivad^` or `Base&`?
>> What is the difference between `T&` and `T^` on assembly level? What
>> can I do with `T^` that is impossible with `T&`?
>>
>> `type_set` is pointless, it should be same as `decltype(comtainer_obj)`
>>
>>
>> >
>> > Mr.marcin said:
>> > Then do not use random symbols.
>> > ****ANSWER****
>> > I used random symbols so I don't have to say "the new expression type 2", but if you have any better name, please please tell me to use that.
>> >
>>
>> To recap expresion is `1` or `1 + 2` or `foo()`, something `T&` like
>> in `void foo(T& a)` is some kind of type. Again please do use terms
>> you know what they mean exactly otherwise you will confuse yourself
>> and everyone else who is trying to read your proposal.
>>
>> > Mr.thiagi said:
>> > >This is not about what the community wants. You're the one proposing. You can
>> > incorporate feedback as it comes. But an incomplete proposal will only get us
>> > going around in circles because we don't see the full picture.
>> >
>> > And you need to be familiar with C++ enough to understand that JIT is not
>> > going to be acceptable without our having to say so.
>> >
>> > ****Answer****
>> > 1. I did try to propose a new value type type but you guys propose other techniques, hence I tried again, but this went slowly. Sorry if this technique caused confusion.
>> > 2. The community did not want values,templates, or operator overloads, not because it was useless, but because no other language (or very few) has them.
>> > 3. I use JIT just as an example on why feedback is important to correct one mistakes. In fact, there have been research papers on why JIT would help C++, but the reason templates or polymorphism in general doesn't incorporate them is because of community feedback. Instead other techniques are used.
>> >
>> >
>> > On Tue, 7 Apr 2026, 7:23 am Marcin Jaczewski, <marcinjaczewski86_at_[hidden]> wrote:
>> >>
>> >> wt., 7 kwi 2026 o 03:08 Muneem via Std-Proposals
>> >> <std-proposals_at_[hidden]> napisał(a):
>> >> >
>> >> > 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)
>> >>
>> >> Then do not use random symbols.
>> >>
>> >> > >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.
>> >>
>> >> This is nowhere close response to Sebastian example. You only repeat
>> >> what you already previously said not addressing this example in any
>> >> way.
>> >> If this `T^` is type, what EXACTLY does it have? And how its even
>> >> possible to have type 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,
>> >>
>> >> `Dispatch` can be pass around, and as far I understand it was the
>> >> point of Sebastian's example.
>> >>
>> >> > 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.
>> >>
>> >> And how its diffrent to `T^`? You too need have somewhere runtime
>> >> index. Where it is?
>> >>
>> >> > 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.
>> >>
>> >> And what bookkeeping is supposedly needed there? I can easily image
>> >> all needed parts in Sebastian and I do not see any missing bits that
>> >> could prevent usage of it. Do you analyze it, or even try to use it or
>> >> dismiss it without even understanding how it works?
>> >>
>> >> > 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.
>> >> >
>> >>
>> >> No, it can, same as your type where you throw an exception if types do
>> >> not match.
>> >> It can be easily implemented by user defined assignment and in it
>> >> check if index point to correct type.
>> >>
>> >> >
>> >> >
>> >> > 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.
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >>

Received on 2026-04-08 01:11:49