|
Программирование >> Обобщенные обратные вызовы
з. Что следует изменить в программе, чтобы она работала так, как, вероятно, ожидает программист? Все, что нам надо, - внести в исходный текст такие изменения, чтобы компилятор не мог рассматривать его как объявление функции. Есть два способа сделать это. Вот более привлекательный способ, пример 29-3(а): устранение неоднозначности при помощи дополнительной пары скобок (неплохое решение; оценка 7/10) deque<strnng> col 13((istream iterator<string>(cin)), istream iterator<string>() ); Здесь мы просто добавили дополнительные скобки вокруг параметра, давая понять компилятору, что мы хотим, чтобы это был параметр конструктора, а не объявление параметра функции. Этот способ срабатывает, поскольку хотя istream iterator<string>(cin) может быть объявлением переменной (или, как уже упоми-налось, объявлением параметра), (istream iterator<string>(cin)) объявлением параметра быть не может. Соответственно, исходный текст примера 29-Зя не может быть объявлением функции по той же причине, по которой не может быть объявлением функции void f ( (int i) ), a именно - из-за наличия дополнительных скобок, которые не могут окружать параметр в объявлении функции. Имеются и другие способы разрешения неоднозначности, которые делают невозможной интерпретацию указанного выражения как объявления функции, но я не буду приводить их здесь по очень простой причине: чтобы эти способы сработали, и вы, и ваш компилятор должны очень хорошо понимать этот темный угол стандарта языка. > Рекомендация Избегайте темных углов языка программирования, включая вполне кор-рсктные конструкции, которые, тем не менее, способны сбивать с толку не только программистов, но даже компиляторы. Описанная неоднозначность синтаксиса по своей природе похожа на острие ножа, по которому лучше не ходить вовсе. а потому лучше полностью избегать использования такого синтаксиса. Я предпочитаю сам и настойчиво рекомендую вам другой способ, существенно более простой и понятный даже не слишком умным компиляторам и, кроме того, облегчающий чтение и понимание текста человеком. Пример 29-3(6): использование именованных переменных (рекомендуемое решение; оценка 10/10) istream iterator<string> fi rst( cin ), last; deque<string> coll3( first, last ); Как в примере 29-Зя, так и в при.мерс 29-36 достаточно внести предлагаемые изменения только в один параметр, но чтобы быть последовательным, я сделал именованными оба параметра. > Рекомендация В качестве аргументов конструктора лучше использовать именованные переменные. Это позволяет избежать возможной неоднозначности между вызовом конструктора и объявлением функции. Кроме того, зачастую это делает более понятным назначение вашего кода и облегчает тем самым его поддержку. Резюме Избегайте пыльных, темных, заросших паутиной углов языка программирования. Профаммисты обычно знают столько, сколько им достаточно для успешной работы. При написании исходного текста помните о необходимости максимальной ясности и однозначности, всегда говорите именно то, что вы хотите сказать. Используйте в качестве аргументов конструктора именованные переменные, чтобы избежать описанных здесь неприятностей и сделать ваш код более ясным, поддерживаемым и сопровождаемым. Задача 30. Двойная точность - вежливость программистов Сложность: 4 Нет, эта задача не об этике. А о том, что есть разные виды плавающей точки . Давайте проверим, насколько хорошо вы разбираетесь в основных операциях с плавающей точкой в С и С++. Вопрос для новичка 1. В чем заключается различие между float и double? Вопрос для профессионала 2. Пусть приведенная далее программа выполняется одну секунду (что достаточно необычно для современных настольных компьютеров). int main О { double x = 1е8; whileC x > О ) { --х; Как вы думаете, сколько времени будет выполняться этот код, если изменить dou-ble на float? Почему? Решение Два слова о float и double 1. В чем заключается различие между float и double? Процитируем отрывок из стандарта С++: Имеется три типа с плавающей точкой: float, double и long double. Тип double обеспечивает, как минимум, ту же точность, что и float, а тип long double - как минимум, ту же точность, что и doub 1е. Множество значений, которые принимает тип float, представляет собой подмножество значений типа double; а множество значений типа double является подмножеством значений типа long double. - [С++03, §3.9.1/8] Как это определение, в особенности его последнее предложение, могут повлиять на ваши исходные тексты? Колесо времени 2. Пусть приведенная далее программа выполняется одну секунду (что достаточно необычно для современных настольных компьютеров). int main С) { double x = leS; whileC X > О ) { Как вы думаете, сколько времени будет выполняться этот код, если изменить double на float? Почему?
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |