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

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

, С++ допускает существование такого кода, и компиляторы в общем случае не выдают при этом никаких предупреждений о нем.

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

• >noexcept является частью интерфейса функции, а это означает, что вызывающий код может зависеть от наличия данного модификатора.

• Функции, объявленные как >noexcept, предоставляют большие возможности оптимизации, чем функции без такой спецификации.

• Спецификация >noexcept имеет особое значение для операций перемещения, обмена, функций освобождения памяти и деструкторов.

• Большинство функций нейтральны по отношению к исключениям, а не являются >nоехсерt-функциями.

3.9. Используйте, где это возможно, >constexpr

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

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

Но давайте начнем с объектов >constexpr. Такие объекты являются, по сути, константными (>const) и на самом деле обладают значениями, известными во время компиляции. (Технически их значения определяются во время трансляции, а трансляция состоит не только из компиляции, но и из компоновки. Однако, если вы не пишете компиляторы или редакторы связей для С++, это не имеет для вас значения, так что можете беспечно программировать так, как будто эти значения объектов >constexpr определяются во время компиляции.)

Значения, известные во время компиляции, являются привилегированными. Они, например, могут быть размещены в памяти, предназначенной только для чтения, и это может представлять особое значение для разработчиков встроенных систем. Широко применяется то, что целочисленные значения, являющиеся константами и известные во время компиляции, могут использоваться в контекстах, где С++ требует целочисленное константное выражение. Такие контексты включают спецификации размеров массивов, целочисленные аргументы шаблонов (включая длину объектов >std::array), значения перечислителей, спецификаторы выравнивания и прочее. Если вы хотите использовать для этих вещей переменные, вы, определенно, захотите объявить их как >constexpr, поскольку тогда компиляторы будут точно знать, что имеют дело со значением времени компиляции:

>int sz;                         // Неконстантная переменная

>…

>constexpr auto arraySize1 = sz; // Ошибка! Значение sz

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

>std::array data1;      // Ошибка! Та же проблема

>constexpr auto arraySize2 = 10; // OK, 10 представляет собой

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

>std::array

>           arraySize2> data2;   // собой constexpr

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

>int sz;                     // Как и ранее

>…

>const auto arraySize = sz;  // OK, arraySize является

>                            // константной копией sz

>std::array

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

Проще говоря, все объекты, являющиеся >constexpr, являются >const, но не все объекты, являющиеся >const, являются >constexpr. Если вы хотите, чтобы компиляторы гарантировали, что переменная имеет значение, которое можно использовать в требующих константы времени компиляции контекстах, то следует использовать >constexpr, а не >const.

Сценарии применения объектов >constexpr становятся более интересными, когда в дело вступают функции >constexpr. Такие функции производят константы времени компиляции, когда они вызываются с константами времени компиляции. Если они вызываются со значениями, неизвестными до времени выполнения, они производят значения времени выполнения. Это может выглядеть так, как будто вы не знаете, что они будут делать, но так думать — неверно. Вот как выглядит правильный взгляд на эти моменты:

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


Еще от автора Скотт Мейерс
Эффективное использование 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 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.