Date: Fri, 10 Apr 2026 13:02:05 -0700
On Friday, 10 April 2026 11:01:28 Pacific Daylight Time Simon Schröder wrote:
> > 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.)
Ah, yes, it is a tuple... thanks. I had seen the size_t tag before and thought
"this is a variant", but that was for Element_t. I replied to the wrong block.
> 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.
I figure it's incomplete.
I also don't see the point of having *all* elements active, like in a tuple.
The original posts talked about having different list types because some were
more suited for a given architecture, but that wouldn't explain why all of
them should be initialised. In that case, the choice is a runtime one, but
constant for the duration of the program.
Having the choice change during execution makes little sense, because now
elements are spread over multiple lists. If you need to find an element, you'd
have to search all of the lists, which defeats the stated purpose of gaining
performance.
> 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).
And like I said, you can manipulate and even assign to the current active type
without changing by using std::visit().
> 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
Indeed.
> 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).
It's not very difficult to write recursive template or maybe template for... and
compare to the variant's index().
> > 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.)
Ah, yes, it is a tuple... thanks. I had seen the size_t tag before and thought
"this is a variant", but that was for Element_t. I replied to the wrong block.
> 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.
I figure it's incomplete.
I also don't see the point of having *all* elements active, like in a tuple.
The original posts talked about having different list types because some were
more suited for a given architecture, but that wouldn't explain why all of
them should be initialised. In that case, the choice is a runtime one, but
constant for the duration of the program.
Having the choice change during execution makes little sense, because now
elements are spread over multiple lists. If you need to find an element, you'd
have to search all of the lists, which defeats the stated purpose of gaining
performance.
> 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).
And like I said, you can manipulate and even assign to the current active type
without changing by using std::visit().
> 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
Indeed.
> 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).
It's not very difficult to write recursive template or maybe template for... and
compare to the variant's index().
-- Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org Principal Engineer - Intel Data Center - Platform & Sys. Eng.
Received on 2026-04-10 20:02:15
