Как и в случае с перегруженными операторами, разумное использование функций преобразования помогает существенно упростить работу разработчика класса и сделать полученный класс удобным в применении. Однако здесь есть две потенциальные ловушки: определение слишком большого количества функций преобразования может привести к неоднозначности кода, а некоторые преобразования могут оказаться скорее вредными, чем полезными.
Для примера рассмотрим класс Date, представляющий данные о дате. Вполне очевидно, что имеет смысл предоставить способ преобразования объекта класса Date в объект типа int. Но какое значение должна возвращать функция преобразования? Она могла бы возвратить десятичное представление года, месяца и дня. Например, 30 июля 1989 года могло бы быть представлено как значение 19800730 типа int. В качестве альтернативы оператор преобразования мог бы возвращать целое число, соответствующее количеству дней, начиная с некоторой эпохальной даты. Счетчик мог бы считать дни с 1 января 1970 года или некой другой отправной точки. У обоих преобразований есть желаемое свойство, что более поздние даты соответствуют большим целым числам, что может быть очень полезно.
Проблема в том, что нет единого и полного соответствия между объектом типа Date и значением типа int. В таких случаях лучше не определять оператор преобразования. Вместо него класс должен определить один или несколько обычных членов, чтобы извлекать эту информацию в различных форматах.
На практике классы редко предоставляют операторы преобразования. Пользователи, вероятней всего, будут просто удивлены, случись преобразование автоматически, без помощи явного преобразования. Но из этого эмпирического правила есть одно важное исключение: преобразование в тип bool является вполне общепринятым для классов.
По прежним версиям стандарта перед классами с преобразованием в тип bool стояла проблема: поскольку тип bool арифметический, объект этого типа, допускающего преобразование в тип bool, применим в любом контексте, где ожидается арифметический тип. Такие преобразования могут происходить весьма удивительными способами. В частности, если бы у класса istream было преобразование в тип bool, то следующий код вполне компилировался бы:
int i = 42;
cin << i; //
//
Эта программа пытается использовать оператор вывода для входного потока. Для класса istream оператор << не определен, поэтому такой код безусловно ошибочен. Но этот код мог бы использовать оператор преобразования в тип bool, чтобы преобразовать объект cin в bool. Полученное значение типа bool было бы затем преобразовано в тип int, который вполне применим как левый операнд встроенной версии оператора сдвига влево. В результате преобразованное значение типа bool (1 или 0) было бы сдвинуто влево на 42 позиции.
Чтобы предотвратить подобные проблемы, новый стандарт вводит
class SmallInt { public:
//