C++ Logo

std-proposals

Advanced search

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

From: Muneem <itfllow123_at_[hidden]>
Date: Sat, 11 Apr 2026 08:00:15 +0500
Mr.thaigo did mistake my heterogeneous list with a variant, but thanks for
reminding him for me. We all rely on community work to correct each other.

My code was just an example of the limitations not the end proposal. Adding
references to variants would dilute the idea of variants, like variants are
supposed to be closed set duck typing mechanisms or as one would say it is
a union with tags. By adding references you are restricting the
union/variant into a strict dynamic type that views an object. The same
goes to tuples, tuples are for compile time typed lists so adding runtime
indexing will dilute the idea and probably make many existing
documentations false. For example the new defintion of what is a standard
layout would suddenly now omit certain specializations variants from the
list. Requiring conversions from a variant of multiple types into an
optional<T&> of a single type will require underlying language support
which again is what I am proposing. The reason I don't want the underlying
implementation support to be wrapped in standard libraries is to not dilute
the existing concepts that already exist, and to let the support provided
be freely expressed. In your case, you can't copy/move because it's wrapped
in the standard library. In my case, it can be copied and moved, since it's
not wrapped in anything. The issue is that at some point you will need
support from the implementation(in your example, conversion from
variants<T&...> to optional<T&> but would you want that support to be
suppressed within the bounds of the interface of the facilities that you
want to extend with that support, or do you want it to be freely expressed
using the language. A good analogy would be:If you are getting a subway
sandwich, get a healthy one with vinegar and multigrain instead of the
"sodium packed" standard sandwich. The standard one is probably considered
more socially acceptable since everyone eats it but it's also more
constraint in that you can't eat too much of it. Same goes over here that
the language one will be free to have its own new interface, ABI, and
everything, but if the same thing is provided by extending the standard
library then even though it is "standard", you can consume the support the
implementation provides completely.

On Fri, 10 Apr 2026, 11:01 pm Simon Schröder via Std-Proposals, <
std-proposals_at_[hidden]> wrote:

> On 10. Apr 2026, at 17:39, Thiago Macieira via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >
> > On Thursday, 9 April 2026 23:30:10 Pacific Daylight Time Muneem via Std-
> > Proposals wrote:
> >> template <std::size_t N, typename type_set, typename... Tail>
> >> class heterogeneous_list_impl;
> >>
> >> template <std::size_t N, typename Head_t, typename... Tail>
> >> class heterogeneous_list<N, Head_t, Tail...> : public
> >> heterogeneous_list_impl<N - 1,Element_t<N, Head_t, Tail...>,Tail...> {
> >> Head_t Element;
> >> public:
> >> using type_set = Element_t<N, Head_t, Tail...>;
> >>
> >> type_set operator[](std::size_t index) {
> >> if (index == N) {
> >> return type_set(Element);
> >> } else if constexpr (N > 0) {
> >> return this->heterogeneous_list_impl<N - 1, type_set,
> >> Tail...>::operator[](index);
> >> } else {
> >> throw std::string{"out of bound access"};
> >> }
> >> }
> >> };
> >
> > You do realise this is just std::variant with one extra operator, right?
> >
> > That operator[] could easily be implemented in the current std::variant,
> with
> > a return either of a new type such as variant_element_ref or simply
> > std::variant<std::add_reference_t<Types>...>. That return type is your
> > innovation, not the heterogeneous list type (which is not a list).
> >
> Thiago, are you now mixing up std::variant and std::tuple? To me, it looks
> like heterogeneous_list is a std::tuple and Element_t is a std::variant.
> However, Element_t has a pointer to the proper element inside the
> heterogeneous_list in Muneems example implementation; so it would be
> comparable to a std::variant that stores a reference. (Which is partially
> what you said.)
>
> I am a little bit confused by the example implementation: I fail to see
> how to actually store values inside the heterogeneous_list. Either there is
> only memory for the first element in the list or there is just a single
> list for each combination of <N,Head_t,Tail…>. I’m not really figuring this
> out by just looking at the code.
>
> Basically, this is what I’ve been saying all along: the heterogeneous list
> can be a std::tuple with an additional operator[] and the return type is a
> special instantiation of std::variant which a) can store references instead
> of just values and b) once assigned cannot change its underlying type. b)
> is easy to achieve by using const std::variant because
> std::variant::operator= is a non-const member function. We might want to
> inherit from std::variant to create a new type with a new name that
> overloads operator= to be able to assign to the currently selected
> underlying type instead of changing the selection (I guess it would be
> really confusing to just add a const overload to std::variant::operator=,
> though technically it would work).
>
> What I’m really missing from the proposed type is that it is always a
> reference to the heterogeneous list. In this way it is not possible for the
> user to choose between reference or copy. I think that this choice is
> really important. Back to a really simple example (I’m gonna use the STL
> types with features that don’t exist):
> std::tuple<int,float> list{1,0.5f}
> const std::variant<int,float> x = list[1]; // ‘1’ could also be a runtime
> value; make a copy of what is stored inside the list
> const std::variant<int&,float&> y = list[0]; // get a reference to the
> object inside the list
> const std::variant<const int&,const float&> z = list[1]; // now we have a
> reference, but cannot change the value inside the list
> It would be helpful if std::variant<Ts&…> and std::variant<const Ts&…>
> would be convertible to std::variant<Ts…> (and std::variant<Ts…> to
> std::variant<const Ts…>).
>
> Getting back to one of the previous examples:
> int^ x = list[0];
> I just noticed that this line could easily be written as
> std::optional<int&> x = list[0];
> This would allow us to write
> *x = 2;
> (if we are cocky and think we know that the optional has a value) or
> x.value() = 2; // throws if x is nullopt
>
> Sure, we could want nicer syntax than x.value(), but at least this simple
> example would work the way Muneem described it (or rather how I understood
> his description). (There was at least a proposal for std::optional<T&> at
> some point; but I’m not sure about its status.) If std::tuple::operator[]
> returns a const std::variant<Ts&…>, we might want to allow conversion from
> std::variant<Ts&…> to std::optional<T&> (where T is one of Ts…). The
> compiler can (or at least should) be able to see right through the optional
> if it knows it is not empty and optimize every access accordingly.
>
> Here is how I would try to implement operator[] for std::tuple:
> const std::variant<Ts&…> std::tuple<Ts&…>::operator[](std::size_t index)
> // also make the member function constexpr
> {
> switch(index)
> {
> case 0:
> return Ts…[0];
> break;
> case 1:
> return Ts…[1];
> break;
> default:
> std::unreachable();
> break;
> }
> }
> We cannot write this by hand for every possible instantiation of the
> tuple, but I assume it is possible to use ’template for’ to fill the switch
> automatically based on the number of entries in the tuple. This would be
> just a couple of lines of code with reflection and no template
> metaprogramming (other than just the regular std::tuple stuff we already
> have).
> Alternatively, we could write ‘return std::get<0>(*this);’ instead of
> ‘return Ts…[0];’ (I might have messed up the syntax because it is one of
> the newer features I haven’t used yet; probably needs to be a value and not
> a type).
>
> This would make the proposal a short list:
> 1. Introduce std::variant<Ts&…>
> 2. Add operator[] to std::tuple which returns const std::variant<Ts&…>
> 3. Add conversion from std::variant<Ts&…> to std::optional<T&>
> 4. Implement lots of optimizations for std::variant and std::optional (and
> std::tuple::operator[] when used at compile time)
>
> It can do (almost) anything requested. And the individual parts are not
> just for this one specific use case. Only the syntax does not look as nice.
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2026-04-11 03:00:33