Skip to main content

Section 14.3 Referencing Rows and Elements

You may have noticed that the previous page described table.at(0) as returning a reference to the first row of the table. The actual prototype for .at() looks something like:
T& vector<T>::at(size_t index);
Recall that T is a placeholder for β€œthe type of data in the vector”. If it is a vector of int, the return type would be int&. This means the function does not return a new integer, it returns a reference to an integer that already exists.
Returning a reference from ordinary functions doesn’t usually make sense. All the local variables in a function are destroyed when the function returns. So if we return a reference to one of those local variables, it will be a reference to a variable that no longer exists. This is not the case with member functions of a vector or a string. The contents of the vector or string will continue to exist after at() has done its work. So it can return a reference to that content.
Returning the reference is what allows the caller to use .at() to modify data. But we need to be careful to use the reference and not make a copy of the data it refers to. For example, if we do this:
int x = table.at(0).at(1);
// x has a copy of the value at row 0, column 1
x = 5; // no change to table
We are copying the value found by table.at(0).at(1) into x. Modifying x would have no effect on the table.
If we want to give a name to the result of table.at(0).at(1), and then use that name to work with the data in the table. We would need to store the result into an int&. That way, the new name is just a reference into the table. The sample below makes a reference called row0col1 that refers to the element at row 0, column 1:
int& row0col1 = table.at(0).at(1);
row0col1 = 3; // changes table
Figure 14.3.1. Memory diagram for table, x, and row0col1.
Similarly, we could make a reference to an entire row. If we wanted to store a reference to an entire row, it would be as a reference to a vector of integers:
vector<int>& row0 = table.at(0);
// row0 is a reference to the first row of the table
cout << row0.size();  // prints 5
row0.at(1) = 3; // changes element at row 0, column 1 in table

Note 14.3.1.

There is no way to ask table for a column of data. If we wanted a column of data, we would have to build it up ourselves by making a new vector, looping through each row to access the data at the column’s index, and add that value to the new vector.
To avoid having to worry about making reference variables, we will favor always specifying the row or element we want to talk about, even if it means saying something like table.at(0).at(1) multiple times in a row. But if you choose to try to make a variable that stores β€œthe current row” or β€œthe element at 0, 1”, make sure to store it as a reference unless your goal is to copy the data.
You have attempted of activities on this page.