Главная » Просмотр файлов » С. Мейерс - Эффективный и современный C++

С. Мейерс - Эффективный и современный C++ (1114942), страница 25

Файл №1114942 С. Мейерс - Эффективный и современный C++ (С. Мейерс - Эффективный и современный C++) 25 страницаС. Мейерс - Эффективный и современный C++ (1114942) страница 252019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 25)

Если вы хотите, чтобы компиляторы гаран­тировали, что переменная имеет значение, которое можно использовать в требующих кон­станты времени компиляции контекстах, то следует использовать constexpr, а не const .Сценарии применения объектов const expr становятся более интересными, когдав дело вступают функции constexpr. Такие функции производят константы времени106Глава 3. Переход к современному С++компиляции, когда они вызь1ваются с константами времени компиляции. Если они вы­зываются со значениями, неизвестными до времени выполнения, они производят значе­ния времени выполнения. Это может выглядеть так, как будто вы не знаете, что они будутделать, но так думать - неверно. Вот как выглядит правильный взгляд на эти моменты:•Функции, объявленные как const expr, могут использоваться в контекстах, требу­ющих константы времени компиляции.

Если значения передаваемых вами аргу­ментов в соnstехрr-функцию в таком контексте известны во время компиляции,результат функции будет вычислен в процессе компиляции. Если любое из значе­ний аргументов неизвестно во время компиляции, ваш код будет отвергнут.•Когда соnstехрr-функция вызывается с одним или несколькими значениями, не­известными во время компиляции, она действует так же, как и обычная функция,выполняя вычисления во время выполнения.

Это означает, что вам не нужны двефункции для выполнения одних и тех же операций, одной - для констант време­ни компиляции, другой - для всех прочих значений. Функция, объявленная какconst expr, выполняет их все.Предположим, что нам нужна структура данных для хранения результатов экспери­мента, который может быть проведен при разных условиях. Например, уровень осве­щения в ходе эксперимента может быть высоким, низким или освещение может бытьотключено вовсе; может быть разная температура, и т.д. Если всего имеется n условий,влияющих на проведение эксперимента, и у каждого по три возможных состояния, то об­щее количество комбинаций составит 3".

Хранение результатов экспериментов для всехкомбинаций условий требует структуры данных с достаточным количеством памятидля хранения 3" значений. В предположении, что каждый результат представляет собойint и что n известно (или может быть вычислено) во время компиляции, подходящимвыбором структуры данных может быть std : : a rray. Однако нам требуется способ вы­числения 3" во время компиляции. Стандартная библиотека С++ предоставляет функциюstd : : pow, обеспечивающую интересующую нас математическую функциональность, нос точки зрения наших целей имеются две проблемы. Во-первых, std : : pow работает с ти­пами с плавающей точкой, а нам нужен целочисленный результат.

Во-вторых, std : : powне является constexpr (т.е. не гарантирует возврат времени компиляции при переданныхей значениях времени компиляции), так что мы не можем использовать ее для указанияразмера std : : a rray.К счастью, мы можем написать функцию pow, которая нам нужна. Как это сделать,я покажу чуть позже, но сначала давайте взглянем, каким образом эта функция можетбыть объявлена и использована:/ / pow является constexprconstexprint pow ( int base, int ехр ) noexcept // Не генерирует исключений! / Ее реализация - ниже3 .9. Испопьэуйте, rде это воэможно, constexpr107constexpr auto nшnConds=5;std : : array<int, роw (З , numConds) >results ;11 Количество условий11 results содержит// з лnшnConds элементовВспомним, что constexpr перед pow не говорит о том, что pow возвращает констант­ное значение; оно говорит, что если base и ехр являются константами времени компиля­ции, то результат pow может быть использован как константа времени компиляции.

Еслиbase и/или ехр не являются константами времени компиляции, то результат pow будетвычисляться во время выполнения. Это означает, что pow может быть вызвана не толькодля вычисления во время компиляции таких вещей, как размер std : : array, но и в кон­тексте времени выполнения, как здесь:11auto base = readFromDB ( "base" ) ;auto ехр = readFromDB ( "exponent " ) ; 1111auto baseToExp = pow (Ьase , ехр) ;11Эти значения получаютсяво время компиляцииВызов функции powво время вьmолненияПоскольку функции constexpr должны быть способны возвращать результаты вовремя компиляции при вызове со значениями времени компиляции, на их реализациинакладываются ограничения. Эти ограничения различны в C++ l l и С++ 1 4.В С++ 1 1 функции constexpr могут содержать не более одной выполнимой инструк­ции - return.

Это выглядит более ограничивающим, чем является на самом деле, по­скольку для повышения выразительности соnstехрr-функций можно использовать двехитрости. Во-первых, можно применять условный оператор " ? : " вместо инструкцииi f- e l se, а во-вторых, вместо циклов можно использовать рекурсию. Таким образом,функция pow может быть реализована следующим образом:constexpr int pow ( int base, int ехр ) noexcept{return (ехр == О ? 1 : base * pow ( base, ехр-1) ) ;Этот код работает, но только очень непритязательный функциональный программистсможет назвать его красивым.

В С++ 14 ограничения на соnst ехрr-функции существеннослабее, так что становится возможной следующая реализация:constexpr i nt pow ( int base , int ехр ) noexcept // С++ 1 4auto result1;for ( int i = О ; i < ехр ; ++i ) result * = base ;return result;=Функции constexpr ограничены приемом и возвратом только литеральных типов(literal types), которые, по сути, означают типы, могущие иметь значения, определяемыево время компиляции. В С++ 1 1 к н им относятся все встроенные типы за исключением108Глава 3.

Переход к современному С++void, но литеральными могут быть и пользовательские типы, поскольку конструкторыи прочие функции-члены также могут являться constexpr:class Point {puЬli c :constexpr Point (douЫe xValО , douЫe yVal0) noexcept: x (xVal ) , y ( yVal ){}constexpr douЫe xValue ( ) const noexceptconstexpr douЫe yVa lue ( ) const noexceptvoid setX (douЫe newX) noexceptvoid setY ( douЫe newY) noexceptprivate :douЫe х, у;};return х ;return у ;х = newX;уnewY;Здесь конструктор Point может быть объявлен как constexpr, поскольку, если пере­данные ему аргументы известны во время компиляции, значения членов-данных создан­ного Point также могут быть известны во время компиляции.

А значит, инициализиро­ванный таким образом объект Point может быть const expr:constexpr Point р1 ( 9 . 4 , 27 . 7 ) ; // ОК, во время компиляции11 работает constexpr конструкторconstexpr Point р2 ( 2 8 . 8 , 5 . 3 ) ; / / То же самоеАналогично функции доступа xVa lue и yVa lue могут быть const expr, поскольку еслиони вызываются для объекта Point со значением, известным во время компиляции (на­пример, объект constexpr Poi nt), значения членов-данных х и у могут быть известныво время компиляции. Это делает возможным написать соnstехрr-функции, которыевызывают функции доступа Point и инициализируют соnstехрr-объекты результатамиВЫЗОВОВ ЭТИХ функций:constexprPoint midpoint ( const Point& p l , const Point& р2 ) noexceptreturn { (pl .

xValue ( ) +p2 . xValue ( ) ) /2 , / / ВьGов constexpr(pl .yValue ( ) +p2 .yValue ( ) ) /2 } ; / / функции - члена/ / Инициализация= midpoint ( p l , р2 ) ;11 constexpr объекта результатом соnstехрr - функцииconstexpr auto midЭто очень интересно. Это означает, что объект mid может быть создан в памяти, пред­назначенной только для чтения, несмотря на то что его инициализация включает вызовыконструкторов, функций доступа и функции, не являющейся членом! Это означает, чтовы можете использовать выражение наподобие mi d .

xVa 1 ue ( } * 1 О в аргументе шаблона3 .9 . Испо л ьзуйте, где это возможно, constexpr1 09или в выражении, определяющем значение перечислителя•! Это означает, что традицион­но довольно строгая граница между работой во время компиляции и работой во времявыполнения начинает размываться, и некоторые вычисления, традиционно являющиесявычислениями времени выполнения, могут перейти на стадию компиляции. Чем боль­ший код участвует в таком переходе, тем быстрее будет работать ваша программа. (Одна­ко компилироваться она может существенно дольше.)В С++ 1 1 два ограничения предотвращают объявление функций-членов Poiпt s et Xи s e t Y как conste xpr.

Во-первых, они модифицируют объект, с которым работают, а вС++ 1 1 функции-члены con s texpr неявно являются con s t . Во-вторых, они имеют возвра­щаемый тип void, а void не является литеральным типом в С++ 1 1 . Оба эти ограничениясняты в С++ 1 4, так что в С++1 4 даже функции установки полей Po i nt могут быть объ­явлены как con s t expr:class PointpuЫ i c :constexpr void setX (douЫe пеwХ) поехсерt / / С++ 1 4newX; }{ х=constexpr void setY (douЫe пеwУ) поехсерt // С++ 1 4{ у = newY; )};Это делает возможным написание функций наподобие следующей:11 Возвращает отражение точки р/ / относительно начала координат (С++1 4 )constexpr Poiпt reflectioп ( const Point& р ) noexceptPoiпt result;resul t .

setX ( -p . xValue ( ) ) ;result . setY ( -p . yValue ( ) ) ;returп result ;/ / Неконстантный объект Point/ / Установка его полей х и у/ / Возврат копииСоответствующий клиентский код имеет вид:constexprconstexprcoпstexprconstexpr•Point р 1 ( 9 . 4 , 27 . 7 ) ; 11 Как и вьnuеPoint р2 ( 2 8 .

8 , 5 . 3 ) ;auto midmidpoiпt (pl , р2 ) ;11 re flectedМid представляетauto re flectedМid==Поскольку P o i n t : : xValue возвращает douЫe, типом m i d . xValue ( ) * 1 0 также является douЫe.Типы с плавающей точкой не могут использоваться для инстанцирования шаблонов или для ука­зания значений перечислений, но они могут быть использованы как части больших выражений,дающих интегральные типы. Например, для и нстанцирования шаблона или для указания значе­ния перечислителя может использоваться выражение s t a t i c_c a s t < i n t > (mi d .

xVa lue ( ) * 1 0 ) .110Гn ава 3 . Переход к современному Cttreflection ( mid) ;11 собой ( - 1 9 . 1 - 1 6 . 5 ) и11 известно во время компиляцииСовет из этого раздела заключается в том, чтобы использовать constexpr везде, гдеэто только возможно, и теперь, надеюсь, вам понятно, почему: и объекты const expr,и соnstехрr-функции могут применяться в более широком диапазоне контекстов, чемобъекты и функции, не являющиеся constexpr. Применяя constexpr, где это возможно,вы максимизируете диапазон ситуаций, в которых ваши объекты и функции могут бытьиспользованы.Важно отметить, что constexpr является частью интерфейса объекта или функции.const e xpr провозглашает: "Меня можно использовать в контексте, где для С++ требу­ется константное выражение". Если вы объявляете объект или функцию как constexpr,клиенты могут использовать их в указанных контекстах. Если позже вы решите, чтотакое использование constexpr было ошибкой, и удалите его, то это может привестик тому, что большое количество клиентского кода перестанет компилироваться.

Характеристики

Тип файла
PDF-файл
Размер
12,67 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6418
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее