Why can we not access elements of a tuple by index?

Because [] is an operator (named operator[]), thus a member function, and is called at run-time.

Whereas getting the tuple item is a template mechanism, it must be resolved at compile time. Which means this can be only done with the <> templating syntax.

To better understand, a tuple may store different types. A template function may return different types depending on the index passed, as this is resolved at compile time. The operator[] must return a unique type, whatever the value of the passed parameter is. Thus the tuple functionality is not achievable.

get<0>(x) and get<1>(x) are two different functions generated at compile time, and return different types. The compiler generates in fact two functions which will be mangled to something like

int get_tuple_int_string_int_0(x)

and

string get_tuple_int_string_int_1(x)

The other answers here address the issue of why this isn't possible to implement, but it's also worth asking the question of whether it should be possible. (The answer is no.)

The subscript operator [] is semantically supposed to indicate dynamically-resolved access to a element of a collection, such as an array or a list (of any implementation). The access pattern generally implies certain things: the number of elements probably isn't known to the surrounding code, which element is being accessed will probably vary at runtime, and the elements are all of the same observable type (thus, to the calling code, interchangeable).

Thing is, a tuple isn't (that kind of) a collection. It's actually an anonymous struct, and its elements aren't interchangeable slots at all - semantically, they are regular fields. What's probably throwing you off is that they happen to be labelled with numbers, but that's really just an anonymous naming pattern - analogous to accessing the elements as x._0, x._1, etc. (The fact you can compute the field names at compile-time is a coincidental bonus enabled by C++'s type system, and is not fundamentally related to what a tuple is; tuples, and this answer, are not really specific to C++.)

So it doesn't support operator[] for the same reason that plain old structs don't support operator[]: there's no semantically-valid use for it in this context. Structures have a fixed set of fields that aren't interchangeable or dynamically computable, and since the tuple is a structure, not a collection, it follows the same rule. Its field names just look different.

Tags:

C++

Stl