Скотт Мейерс - Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14
- Название:Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2016
- Город:Москва
- ISBN:978-5-8459-2000-3
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Скотт Мейерс - Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 краткое содержание
В книге рассматриваются следующие темы. Освоение С++11 и С++14 — это больше, чем просто ознакомление с вводимыми этими стандартами возможностями (например, объявлениями типов
, семантикой перемещения, лямбда-выражениями или поддержкой многопоточности). Вопрос в том, как использовать их эффективно, чтобы создаваемые программы были корректны, эффективны и переносимы, а также чтобы их легко можно было сопровождать. Именно этим вопросам и посвящена данная книга, описывающая создание по-настоящему хорошего программного обеспечения с использованием C++11 и С++14 — т.е. с использованием современного С++.
■ Преимущества и недостатки инициализации с помощью фигурных скобок, спецификации
, прямой передачи и функций
интеллектуальных указателей
■ Связь между
,
, rvalue-ссылками и универсальными ссылками
■ Методы написания понятных, корректных,
лямбда-выражений
■ Чем
отличается от
, как они используются и как соотносятся с API параллельных вычислений С++
■ Какие из лучших методов “старого” программирования на С++ (т.е. С++98) должны быть пересмотрены при работе с современным С++
Более чем 20 лет книги
серии
являются критерием уровня книг по программированию на С++. Понятное пояснение сложного технического материала принесло ему всемирную известность. Он всегда самый желанный гость на международных конференциях, а его услуги консультанта широко востребованы во всем мире.
Скотт Мейерс Эффективный и современный С++, После изучения основ С++ я перешел к изучению того, как применять С++ в промышленном программировании, с помощью серии книг Скотта Мейерса Эффективный С++. Эффективный и современный С++ — наиболее важная из книг серии, предлагающая ключевые рекомендации, стили и идиомы, позволяющие эффективно использовать современный С++. Вы еще не купили эту книгу? Сделайте это прямо сейчас. Герб Саттер,
глава Комитета ISO по стандартизации С++, специалист в области архитектуры программного обеспечения на С++ в Microsoft
Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
void setup(); // Функции, определенные в другом месте
void cleanup();
void doWork() noexcept {
setup(); // Настройка для выполнения некоторой работы
… // Выполнение работы
cleanup(); // Очистка после выполнения работы
}
Здесь функция doWork
объявлена как noexcept
, несмотря на то, что она вызывает функции setup
и cleanup
без такого модификатора. Это кажется противоречием, но ведь может быть так, что функции setup
и cleanup
документированы как не генерирующие исключений, пусть при этом они и не объявлены как noexcept
. Для такого их объявления могут иметься некоторые веские причины. Например, они могут быть частью библиотеки, написанной на языке программирования С. (Даже у функций стандартной библиотеки С, перемещенных в пространство имен std
, отсутствуют спецификации исключений; например, std::strlen
не объявлена как noexcept
.) Они также могут быть частью стандартной библиотеки С++98, в которой решено не использовать спецификации исключений С++98 и которая еще не пересмотрена на предмет использования возможностей С++11.
Поскольку для функций, объявленных как noexcept
, имеются законные основания полагаться на код, не имеющий гарантии noexcept
, С++ допускает существование такого кода, и компиляторы в общем случае не выдают при этом никаких предупреждений о нем.
• 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
-функцию в таком контексте известны во время компиляции, результат функции будет вычислен в процессе компиляции. Если любое из значений аргументов неизвестно во время компиляции, ваш код будет отвергнут.
• Когда constexpr
-функция вызывается с одним или несколькими значениями, неизвестными во время компиляции, она действует так же, как и обычная функция, выполняя вычисления во время выполнения. Это означает, что вам не нужны две функции для выполнения одних и тех же операций, одной — для констант времени компиляции, другой — для всех прочих значений. Функция, объявленная как constexpr
, выполняет их все.
Интервал:
Закладка: