C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Extension to std::tuples to allow runtime indexing.

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Thu, 16 Apr 2026 23:56:56 -0400
On Thu, Apr 16, 2026 at 10:26 PM Muneem via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> Abstract: This proposal provides a specialization of std::tuple that can be indexed at runtime. It also introduces specializations for std::variant and std::optional to ensure the interface of such a tuple remains efficient.
> I wrote 3 files, the first was a complete draft that I am gonna paste as a txt file, the second was a formatted docx file that I wanted to float around the internet to get some feedback before I post it over here (sadly no on was interested in the poor man's document), and the third is the shortened version where I removed all the code and kept it conceptual. Sorry for pasting three files at once, but I just wanted to see which one is acceptable and which one isn't. Personally, I like the first two.

Your proposal is full of key statements that you say confidently, as
if they were self-evidently true, but you offer no evidence for it
(anecdotal or otherwise). And these aren't minor nit-picks; they're
*foundational* to the choices your proposal makes.

For example:

> Existing tuples cannot be optimized for runtime indexing without breaking ABI (Application Binary Interface).

Where's the evidence for it?

A tuple is just a struct that uses compile-time numeric indices
instead of compile-time names. If you use a compile-time name or
compile-time index, this is converted into an address within the
"struct". For every struct member, there is a byte offset from the
start of the struct to that member.

The thing that determines what the byte offset is for a given member
is the implementation of the tuple/struct. This is baked into the ABI
of the object. Which means that the *only part* of this process that
is in any way ABI dependent is the specific mapping from an index to a
byte offset..

Your hypothetical runtime-optimized tuple would also have a way to
convert an index into a byte offset. Every member would have a
separate byte offset. So... why would one mapping of index:byte-offset
be inherently slower at runtime than a different one? Why does ABI
matter *at all* for converting a runtime index to a byte offset?

The veracity of your statement is the core reason why your proposal
uses a `tuple` specialization. That is, if this statement is untrue,
then there's no reason to not just allow any `tuple` to be able to use
runtime indexing.

So if you're going to make that a part of your proposal, it needs to
actually justify this statement.

Similarly:

> This also means common implementations of variants (tagged unions or "closed set unions") might not suffice. Instead, implementations should use techniques similar to typeid or other internal mechanisms.

Um... why not?

A reference is just a pointer. A variant of references is really just
a variant of pointers. And pointers are all the same size. So a
variant holding a union of pointers is functionally no different from
a variant holding a `void*` that it casts to the appropriate type as
needed.

The only optimization I could see is if an implementation is able to
hide the index somewhere inside the `void*` itself, using bits in the
address that are otherwise unused. But I'm not sure that's faster than
just adding a byte before the `void*`.

Again, if you have some evidence for this statement, put it into the paper.

On a different topic:

> The main reason for this variant specialization to exist is that it cannot be valueless.

Specializations of a template should not radically alter the
fundamental behavior of the core template. `vector<bool>` is a bad
idea because its interface and behavior does not match what `vector`
is supposed to mean. The same goes for this `variant`; it should work
just like any other `variant`. You should be able to assign to it,
change the bound type, etc. And if it can't do those things, there
needs to be a *very* good reason as to why it doesn't.

And feeling that valueless by exception is icky is not a good reason.

If you don't want runtime indexing of a `tuple` to return a `variant`
that actually does what a `variant` does, then it should be a new type
with a new name.

Received on 2026-04-17 03:57:09