const_cast
and OverloadingIn § 4.11.3 (p. 163) we noted that const_cast
s are most useful in the context of overloaded functions. As one example, recall our shorterString
function from § 6.3.2 (p. 224):
// return a reference to the shorter of two strings
const string &shorterString(const string &s1, const string &s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
Advice: When Not to Overload a Function Name
Although overloading lets us avoid having to invent (and remember) names for common operations, we should only overload operations that actually do similar things. There are some cases where providing different function names adds information that makes the program easier to understand. Consider a set of functions that move the cursor on a Screen
.
Screen& moveHome();
Screen& moveAbs(int, int);
Screen& moveRel(int, int, string direction);
It might at first seem better to overload this set of functions under the name move
:
Screen& move();
Screen& move(int, int);
Screen& move(int, int, string direction);
However, by overloading these functions, we’ve lost information that was inherent in the function names. Although cursor movement is a general operation shared by all these functions, the specific nature of that movement is unique to each of these functions. moveHome
, for example, represents a special instance of cursor movement. Whether to overload these functions depends on which of these two calls is easier to understand:
// which is easier to understand?
myScreen.moveHome(); // we think this one!
myScreen.move();
This function takes and returns references to const string
. We can call the function on a pair of nonconst string
arguments, but we’ll get a reference to a const string
as the result. We might want to have a version of shorterString
that, when given nonconst
arguments, would yield a plain reference. We can write this version of our function using a const_cast
:
string &shorterString(string &s1, string &s2)
{
auto &r = shorterString(const_cast<const string&>(s1),
const_cast<const string&>(s2));
return const_cast<string&>(r);
}
This version calls the const
version of shorterString
by casting its arguments to references to const
. That function returns a reference to a const string
, which we know is bound to one of our original, nonconst
arguments. Therefore, we know it is safe to cast that string
back to a plain string&
in the return.