Angew's answer presents an interesting and useful idiom:
- A variable that cannot be directly modified by the program in a desirable way.
- Creating a utility class that holds a reference to the variable.
- Modifying the variable via the reference held in a temporary instance of that class.
This works because the program has an handle to the variable via the reference and hence, modify the variable. When the reference is destroyed along with the temporary instance of the class, the variable that is referred to is not affected.
Here is another example of this idiom.
For the current question, the idiom could be implemented in this way also, which is somewhat simpler to follow:
struct CharWidthNum {
char &c;
CharWidthNum(char &c) : c(c) {}
};
// Note: the temporary instance of CharWidthNum can be passed as an rvalue
// reference or as a const reference. It is the variable to which the reference
// variable refers to that is getting modified.
template <typename T, typename Traits>
std::basic_istream<T, Traits> &operator>>(std::basic_istream<T, Traits> &str,
CharWidthNum &&c) {
short i;
str >> i;
c.c = i; // static_cast<char> is not necessary when assigning an
// integer type to char.
return str;
}
In the program,
char selection;
std::cin>>CharWidthNum(selection);
We are directly creating a temporary instance of the utility struct, instead of using a utility function that returns a copy of that struct.