В старых (читай: вскоре после cfront
) компиляторах C ++ компилятору не гарантировалось неявно вызывать операторы типов при необходимости.Если iostream
не имеет объявленного operator !
, вы не можете ожидать, что !cout
будет работать во всех случаях.C ++ 89 (или как там назывался стандарт до C ++ 98) просто оставил область неопределенной.
По этой же причине operator void*()
был перегружен, а не operator int
или operator bool
.(bool
даже не существовал как собственный тип в стандарте на тот момент.) Я помню, как мой профессор говорил мне, что if()
под капотом ожидал void*
в C ++, потому что этот тип мог действовать кактип «superset» относительно тех типов результатов выражения, которые будут переданы в оператор if
, но я нигде не нашел это прописанным.
Это было во времена gcc 2, когда большинство людейне поддерживал шаблоны или исключения, или, если они это делали, не поддерживал их полностью, поэтому метапрограммирование C ++ с помощью шаблонов все еще было теоретическим упражнением, и вы должны убедиться, что operator new
не возвращает нулевой указатель.
Это сводило меня с ума в течение нескольких лет.
Интересная выдержка из Страуструпа Язык программирования C ++ , 3-е изд.(1997), стр. 276:
Типы istream и ostream полагаются на функцию преобразования для включения операторов, таких как
while (cin >> x) cout << x;
Операция ввода cin >> x возвращает istream & .Это значение неявно преобразуется в значение, указывающее состояние cin .Затем значение можно проверить с помощью , тогда как .Однако обычно не хорошая идея для определения неявного преобразования из одного типа в другой таким образом, что при преобразовании теряется информация.
Существует многоС ++, который кажется милой или умной победой над последовательной.Я бы не возражал, если бы C ++ был достаточно умен, чтобы обрабатывать цикл, описанный выше, так:
while (!(cin >> x).fail()) cout << x;
, потому что это, хотя и более многословно и более пунктуально, понятнее начинающему программисту.* ... На самом деле, если подумать, мне не нравится ни одна из этих конструкций.Объясните это:
for(;;)
{ cin >> x;
if(!cin)
break;
cout << x;
}
Почему мне это нравится больше?Потому что эта версия значительно упрощает процесс расширения кода, скажем, для обработки двух операций чтения за раз вместо одного.Например, «Существующий код копирует последовательность значений с плавающей запятой. Мы хотим, чтобы вы изменили ее, чтобы она объединяла значения с плавающей запятой и записывала их по два на строку, поскольку теперь мы используем комплексные числа».
Но я отвлекся.