Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - [45]

Шрифт
Интервал

также могут быть известны во время компиляции. А значит, инициализированный таким образом объект >Point может быть >constexpr:

>constexpr Point p1(9.4, 27.7); // OK, во время компиляции

>                               // работает constexpr конструктор

>constexpr Point p2(28.8, 5.3); // То же самое

Аналогично функции доступа >xValue и >yValue могут быть >constexpr, поскольку если они вызываются для объекта >Point со значением, известным во время компиляции (например, объект >constexpr Point), значения членов-данных >x и >y могут быть известны во время компиляции. Это делает возможным написать >constexpr-функции, которые вызывают функции доступа >Point и инициализируют >constexpr-объекты результатами вызовов этих функций:

>constexpr

>Point midpoint(const Points p1, const Points p2) noexcept {

> return {(p1.xValue()+p2.xValue()) / 2,  // Вызов constexpr

>         (p1.yValue()+p2.yValue()) / 2}; // функции-члена

>}


>constexpr auto mid = midpoint(p1, p2);   // Инициализация

>       // constexpr объекта результатом constexpr-функции

Это очень интересно. Это означает, что объект >mid может быть создан в памяти, предназначенной только для чтения, несмотря на то что его инициализация включает вызовы конструкторов, функций доступа и функции, не являющейся членом! Это означает, что вы можете использовать выражение наподобие >mid.xValue() * 10 в аргументе шаблона или в выражении, определяющем значение перечислителя[10]! Это означает, что традиционно довольно строгая граница между работой во время компиляции и работой во время выполнения начинает размываться, и некоторые вычисления, традиционно являющиеся вычислениями времени выполнения, могут перейти на стадию компиляции. Чем больший код участвует в таком переходе, тем быстрее будет работать ваша программа. (Однако компилироваться она может существенно дольше.)

В С++11 два ограничения предотвращают объявление функций-членов >Point>setX и >setY как >constexpr. Во-первых, они модифицируют объект, с которым работают, а в С++11 функции-члены >constexpr неявно являются >const. Во-вторых, они имеют возвращаемый тип >void, а >void не является литеральным типом в С++11. Оба эти ограничения сняты в С++14, так что в С++14 даже функции установки полей >Point могут быть объявлены как >constexpr:

>class Point {

>public:


> constexpr void setX(double newX) noexcept // С++14

> { x = newX;}


> constexpr void setY(double newY) noexcept // С++14

> { y = newY; }


>};

Это делает возможным написание функций наподобие следующей:

>// Возвращает отражение точки p

>// oтнocитeльнo начала координат (С++14)

>constexpr Point reflection(const Point& p) noexcept {

> Point result;             // Нeкoнcтантный объект Point

> result.setX(-p.xValue()); // Установка его полей x и y

> result.setY(-p.yValue());

> return result;            // Возврат копии

>}

Соответствующий клиентский код имеет вид:

>constexpr Point p1(9.4, 27.7); // Как и выше

>constexpr Point p2(28.8, 5.3);

>constexpr auto mid = midpoint(p1, p2);

>constexpr auto reflectedMid = // reflectedMid пpeдcтавляeт

> reflection(mid);             // собой (-19.1 -16.5) и

>                              // известно во время компиляции

Совет из этого раздела заключается в том, чтобы использовать >constexpr везде, где это только возможно, и теперь, надеюсь, вам понятно, почему: и объекты >constexpr, и >constexpr-функции могут применяться в более широком диапазоне контекстов, чем объекты и функции, не являющиеся >constexpr. Применяя >constexpr, где это возможно, вы максимизируете диапазон ситуаций, в которых ваши объекты и функции могут быть использованы.

Важно отметить, что >constexpr является частью интерфейса объекта или функции. >constexpr провозглашает: “Меня можно использовать в контексте, где для С++ требуется константное выражение”. Если вы объявляете объект или функцию как >constexpr, клиенты могут использовать их в указанных контекстах. Если позже вы решите, что такое использование >constexpr было ошибкой, и удалите его, то это может привести к тому, что большое количество клиентского кода перестанет компилироваться. (Простое действие, заключающееся в добавлении в функцию отладочного вывода для отладки или настройки производительности может привести к таким проблемам, поскольку инструкции ввода-вывода в общем случае в >constexpr-функциях недопустимы.) Часть “где это возможно” совета является вашей доброй волей на придание долгосрочного характера данному ограничению на объекты и функции, к которым вы его применяете.

Следует запомнить

• Объекты >constexpr являются константными и инициализируются объектами, значения которых известны во время компиляции.

• Функции >constexpr могут производить результаты времени компиляции при вызове с аргументами, значения которых известны во время компиляции.

• Объекты и функции >constexpr могут использоваться в более широком диапазоне контекстов по сравнению с объектами и функциями, не являющимися >constexpr.

• >constexpr является частью интерфейса объектов и функций.

3.10. Делайте константные функции-члены безопасными в смысле потоков

Если мы работаем в области математики, нам может пригодиться класс, представляющий полиномы. В этом классе было бы неплохо иметь функцию для вычисления корней полинома, т.e. значений, при которых значение полинома равно нулю. Такая функция не должна модифицировать полином, так что ее естественно объявить как


Еще от автора Скотт Мейерс
Эффективное использование STL

В этой книге известный автор Скотт Мейерс раскрывает секреты настоящих мастеров, позволяющие добиться максимальной эффективности при работе с библиотекой STL.Во многих книгах описываются возможности STL, но только в этой рассказано о том, как работать с этой библиотекой. Каждый из 50 советов книги подкреплен анализом и убедительными примерами, поэтому читатель не только узнает, как решать ту или иную задачу, но и когда следует выбирать то или иное решение — и почему именно такое.


Как функции, не являющиеся методами, улучшают инкапсуляцию

Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Платформа J2Me

Эта книга научит вас, как разрабатывать программное обеспечение для платформы J2ME компании «Sun Microsystems». Эта книга придерживается стиля учебного пособия, это не справочное руководство.Цель — дать вам твердую основу в понятиях и техниках, которая даст вам возможность решиться на самостоятельную разработку качественных приложений.


Виртуальная библиотека Delphi

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка баз данных на Visual Basic.NET

Это практическое руководство разработчика программного обеспечения на Visual Basic .NET и ADO.NET, предназначенное для создания приложений баз данных на основе WinForms, Web-форм и Web-служб. В книге описываются практические способы решения задач доступа к данным, с которыми сталкиваются разработчики на Visual Basic .NET в своей повседневной деятельности. Книга начинается с основных сведений о создании баз данных, использовании языка структурированных запросов SQL и системы управления базами данных Microsoft SQL Server 2000.


Исчерпывающее руководство по написанию всплывающих подсказок

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Программное обеспечение встроенных систем. Общие требования к разработке и документированию

Embedded system software. General requirements for development and documentationСтандарт подготовлен в развитие ГОСТ Р ИСО/МЭК 12207-99 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.