Demystifying the Sparse Array Implementation

The full implementation of the sparse array container from assignment 04 only has about 300 lines, but only a few code sections are actually relevant. Let’s implement it step by step.

We start by defining the container interface and do not care about its implementation for now.

The template parameters are specified already, and obviously the container has to define iterator and const_iterator types.

As mentioned in the assignment, you can copy the interface of std::array for a starting point. As sparse_array is a drop-in replacement for std::array, their method signatures must be identical anyways.

This section only discusses the non-trivial aspects of the implementation that differ from std::array.

If you can take the address of an expression, the expression is an lvalue.

If the type of an expression is an lvalue reference (e.g., T& or const T&, etc.), that expression is an lvalue.

Otherwise, the expression is an rvalue.
Conceptually (and typically also in fact), rvalues correspond to temporary objects, such as those returned from functions or created through implicit type conversions. Most literal values (e.g., 10 and 5.3) are also rvalues.

With the advent of move semantics in the C++11 standard, the terminology had to be refined.

Terminology

NOTE: This subsection is provided for the sake of completeness. I do neither expect nor encourage you to deep-dive into value category formalities (yet).

Each C++ expression is characterized by two independent properties: a type and a value category.
The three primary value categories are:

prvalue (pure rvalue)

Either computes the value of the operand of an operator or an expression that initializes an object
Example: result of calling a function whose return type is not a reference

xvalue (expiring value)

An object whose resources can be reused

lvalue (left-value)

a function or object, historically named lvalues as they could appear on the left-hand side of an assignment expression

Naming and definitions of value categories have changed in the C++ standard’s history.

An rvalue (right-value) is a prvalue or xvalue.
A glvalue (generalized lvalue) is an lvalue or xvalue.

Consequently, xvalue can refer to either rvalue or lvalue.

Note that value categories refer to expressions, not just to variables or values, despite their naming.
For example, a ? b : c is an xvalue.