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

Related searches
tuple <int, string, int> x=make_tuple(1, "anukul", 100);
cout << x[0];       //1
cout << get<0>(x);  //2

2 works. 1 does not.

Why is it so?

From Lounge C++ I learnt that it is probably because the compiler does not know what data type is stored at that index. But it did not make much sense to me as the compiler could just look up the declaration of that tuple and determine the data type or do whatever else is done while accessing other data structures' elements 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)

Python - Tuples, The index() method returns the index of the specified element in the tuple. in the tuple. If the element is not found, a ValueError exception is raised. print(' The index of e:', index) # element 'i' is searched # index of the first 'i' is returned index = vowels.index('i') print('The index of i:', index) Information storage and access. Tuple index() parameters. The tuple index() method can take a maximum of three arguments:. element - the element to be searched; start (optional) - start searching from this index

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.

Python Tuple (With Examples), When we do not want to change the data over time, the tuple is a preferred data Indexes starts with 0 that is why we use 0 to access the first element of tuple,� While working with tuples, we store different data as different tuple elements. Sometimes, there is a need to print a specific information from the tuple. For instance, a piece of code would want just names to be printed of all the student data. Lets discuss certain ways how one can achieve solutions to this problem.

It's not very clean supporting operator[] given you can't vary the static return type to match the accessed element. If the Standard Library had incorporated something like boost::any or boost::variant, it would make more sense.

Put another way, if you write something like:

int n = atoi(argv[1]);
int x = x[n];

Then what should it do if n doesn't address an int member of the tuple? To even support checking you'd need to store some manner of RunTime Type Information for tuples, which is extra overhead in the executable/memory.

Python Tuple index(), If the tuple elements are not immutable, their properties can be changed. But, we can't We can access tuple elements through their index. It also supports� The index function takes a single argument as the tuple element to pass. String elements of the tuple can be pass as the argument within the double quotes(”). While integer elements of the tuple can be pass as the argument without the quotes(”). See the example below to get the index of your tuple element in Python.

It can be supported, it just needs to take a compile-time index. Since parameters of a function cannot be made constexpr, we need to wrap the index within a type and pass that instead. (e.g. std::integral_constant<std::size_t, N>.

The following is an extension of std::tuple that supports operator[].

template <typename... Ts>
class tuple : public std::tuple<Ts...> {
  public:
  using std::tuple<Ts...>::tuple;

  template <std::size_t N>
  decltype(auto) operator[](std::integral_constant<std::size_t, N>) {
    return std::get<N>(*this);
  }
};

It would be used like so:

tuple<int, std::string> x(42, "hello");
std::cout << x[std::integral_constant<std::size_t, 0>{}] << std::endl;
// prints: 42

To mitigate the std::integral_constant crazy, we can use variable template:

template <std::size_t N>
std::integral_constant<std::size_t, N> ic;

With this, we can say:

std::cout << x[ic<1>] << std::endl;  // prints: hello

So it could be done. One guess as to why this is currently not available is because features such as std::integral_constant and variable templates may not have existed at the time std::tuple was introduced. As to why it doesn't exist even though those features exist, I would guess it's because no one have yet to proposed it.

Python Tuple with example, Delete an element at specific index in tuple. To delete the element at index n in tuple we will use the same slicing logic as above, but we will slice the tuple from from (0 to n-1) and (n+1 to end) i.e. # Sliced copy containing elements from 0 to n-1 tupleObj[ : n] # Sliced copy containing elements from n to end tupleObj[n + 1 : ]

Because tuple has no operator "bracket". Why is it so? You cannot resolve templates based only on the return value. You cannot write

template<typename T>
T tuple::operator [](size_t i) const ;

Which is absolutely necessary to be able to allow statements like x[0]

Python Tuple - An Immutable Sequence, For each TupleN type, where 1 <= N <= 22, Scala defines a number of element-access methods. Given the following definition − val t = (4,3,2,1) To access elements of a tuple t, you can use method t._1 to access the first element, t._2 to access the second, and so on. For example, the following expression computes the sum of all elements of t.

Access Tuple Elements. There are various ways in which we can access the elements of a tuple. 1. Indexing. We can use the index operator [] to access an item in a tuple, where the index starts from 0. So, a tuple having 6 elements will have indices from 0 to 5.

Change Tuple Values. Once a tuple is created, you cannot change its values. Tuples are unchangeable, or immutable as it also is called.. But there is a workaround. You can convert the tuple into a list, change the list, and convert the list back into a tuple.

First, convert tuple to list by built-in function list (). You can always update an item to list object assigning new value to element at certain index. Then use another built-in function tuple () to convert this list object back to tuple.

Comments
  • BTW, imho the correct pattern would have been x.0
  • @PaoloM except function names cannot start with a number.
  • duplicate? that's a long stretch!
  • @UmNyobe Hmmm, I don't know why Community did that? But the reason this can't be done is very well documented in the other question's answers.
  • @TartanLlama I was meaning that an std::tuple is much more an unnamed struct than an array of something
  • Type-theoretically, tuples and records are both product types, with the only difference being that a record's components are labeled, and a tuple's aren't. So, yes, a tuple is pretty much exactly the same as a struct (which is how C++ spells "record") with anonymous fields.
  • can we not use auto (C++ 14) ?
  • @AnukulSangwan: no - auto must be able to work out a specific type at compile time, so it knows how much memory to reserve for the object, which destructor to call etc..
  • Variable templates definitely didn't exist then, and as your example shows, the syntax is pretty gross without them (although we could have done it with the placeholders from std::bind, i.e. x[_1], if they weren't one-based indices rather than zero-based!). I totally agree the reason we don't have it is the usual answer to "why isn't this in the standard?!" ... nobody proposed it. Maybe you should :)
  • Why is integer constant needed? Wouldnt consexpr be enough?