14.5. Subscript Operator
Classes that represent containers from which elements can be retrieved by position often define the subscript operator, operator[]
.
INFO
Exercises Section 14.4
Exercise 14.20: Define the addition and compound-assignment operators for your Sales_data
class.
Exercise 14.21: Write the Sales_data
operators so that +
does the actual addition and +=
calls +
. Discuss the disadvantages of this approach compared to the way these operators were defined in § 14.3 (p. 560) and § 14.4 (p. 564).
Exercise 14.22: Define a version of the assignment operator that can assign a string
representing an ISBN to a Sales_data
.
Exercise 14.23: Define an initializer_list
assignment operator for your version of the StrVec
class.
Exercise 14.24: Decide whether the class you used in exercise 7.40 from § 7.5.1 (p. 291) needs a copy- and move-assignment operator. If so, define those operators.
Exercise 14.25: Implement any other assignment operators your class should define. Explain which types should be used as operands and why.
INFO
The subscript operator must be a member function.
To be compatible with the ordinary meaning of subscript, the subscript operator usually returns a reference to the element that is fetched. By returning a reference, subscript can be used on either side of an assignment. Consequently, it is also usually a good idea to define both const
and nonconst
versions of this operator. When applied to a const
object, subscript should return a reference to const
so that it is not possible to assign to the returned object.
TIP
Best Practices
If a class has a subscript operator, it usually should define two versions: one that returns a plain reference and the other that is a const
member and returns a reference to const
.
As an example, we’ll define subscript for StrVec
(§ 13.5, p. 526):
class StrVec {
public:
std::string& operator[](std::size_t n)
{ return elements[n]; }
const std::string& operator[](std::size_t n) const
{ return elements[n]; }
// other members as in § 13.5 (p. 526)
private:
std::string *elements; // pointer to the first element in the array
};
We can use these operators similarly to how we subscript a vector
or array. Because subscript returns a reference to an element, if the StrVec
is nonconst
, we can assign to that element; if we subscript a const
object, we can’t:
// assume svec is a StrVec
const StrVec cvec = svec; // copy elements from svec into cvec
// if svec has any elements, run the string empty function on the first one
if (svec.size() && svec[0].empty()) {
svec[0] = "zero"; // ok: subscript returns a reference to a string
cvec[0] = "Zip"; // error: subscripting cvec returns a reference to const
}
INFO
Exercises Section 14.5
Exercise 14.26: Define subscript operators for your StrVec
, String
, StrBlob
, and StrBlobPtr
classes.