Скотт Мейерс - Эффективный и современный С++. 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 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
std::remove_const::type // C++11: const T -> T
std::remove_const _t // Эквивалент в С++14
std::remove_reference::type // C++11: T&/Т&& -> T
std::remove_reference _t // Эквивалент в С++14
std::add_lvalue_reference::type // C++11: T -> T&
std::add_lvalue_reference_t // Эквивалент в С++14
Конструкции С++11 остаются в силе в С++14, но я не знаю, зачем вам может захотеться их использовать. Даже если у вас нет компилятора С++ 14, написание таких шаблонов псевдонимов самостоятельно — детская игра. Требуются только языковые возможности С++11, и даже ребенок сможет написать такие шаблоны. Если у вас есть доступ к электронной копии стандарта С++14, то все становится еще проще — вы можете просто скопировать необходимый код оттуда и вставить в свою программу. Вот вам для начала:
template
using remove_const_t = typename remove_const::type;
template
using remove_reference_t = typename remove_reference::type;
template
using add_lvalue_reference_t =
typename add_lvalue_reference::type;
Судите сами — что может быть проще?
• В отличие от объявлений псевдонимов, typedef
не поддерживает шаблонизацию.
• Шаблоны псевдонимов не требуют суффикса “ ::type
”, а в шаблонах — префикса typename
, часто требуемого при обращении к typedef
.
• С++14 предлагает шаблоны псевдонимов для всех преобразований свойств типов C++11.
3.4. Предпочитайте перечисления с областью видимости перечислениям без таковой
В качестве общего правила объявление имени в фигурных скобках ограничивает видимость этого имени областью видимости, определяемой этими скобками. Но не так обстоит дело с перечислениями в С++98. Имена в таких перечислениях принадлежат области видимости, содержащей enum
, а это означает, что ничто иное в этой области видимости не должно иметь такое же имя:
enum Color { black, white, red}; // black, white, red находятся
// в той же области видимости,
// что и Color
auto white= false; // Ошибка! white уже объяв-
// лено в этой области видимости
Тот факт, что эти имена перечисления “вытекают” в область видимости, содержащую определение их enum
, приводит к официальному термину для данной разновидности перечислений: без области видимости (unscoped). Их новый аналог в С++11, перечисления с областью видимости (scoped enum), не допускает такой утечки имен:
enum classColor
{ black, white, red }; // black, white, red принадлежат
// области видимости Color
auto white= false; // OK, других white нет
Color с = white; // Ошибка! Нет имени перечисления
// "white" в этой области видимости
Color с = Color::white; // OK
auto с = Color::white; // OK (и соответствует совету
// из раздела 2.1)
Поскольку enum
с областью видимости объявляются с помощью ключевого слова class
, о них иногда говорят как о классах перечислений .
Снижение загрязнения пространства имен, обеспечиваемое применением перечислений с областью видимости, само по себе является достаточной причиной для предпочтения таких перечислений их аналогам без областей видимости. Однако перечисления с областью видимости имеют и второе убедительное преимущество: они существенно строже типизированы. Значения в перечислениях без областей видимости неявно преобразуются в целочисленные типы (а оттуда — в типы с плавающей точкой). Поэтому вполне законными оказываются такие семантические карикатуры:
enum Color {black, white, red}; // Перечисление без
// области видимости
std::vector // Функция, возвращающая
primeFactors(std::size_t x); // простые делители x
Color с = red;
…
if (с < 14.5) { // Сравнение Color и double (!)
auto factors = // Вычисление простых делителей
primeFactors(c); // значения Color (!)
}
Добавление простого ключевого слова class
после enum
преобразует перечисление без области видимости в перечисление с областью видимости, и это — совсем другая история. Не имеется никаких неявных преобразований элементов перечисления с областью видимости в любой другой тип:
enum classColor // Перечисление с областью видимости
{black, white, red};
Color с = Color::red; // Как и ранее, но с квалификатором
// области видимости
if (с < 14.5) { // Ошибка! Нельзя сравнивать
// Color и double
auto factors = // Ошибка! Нельзя передавать Color в
primeFactors(c); // функцию, ожидающую std::size_t
}
Если вы хотите честно выполнить преобразование из Color
в другой тип, сделайте то же, что вы всегда делаете для осуществления своих грязных желаний, — воспользуйтесь явным приведением типа:
if ( static_cast(c )< 14.5) { // Странный, но
// корректный код
auto factors = // Сомнительно, но компилируется
primeFactors ( static_cast(c ));
}
Может показаться, что перечисления с областями видимости имеют и третье преимущество перед перечислениями без областей видимости, поскольку могут быть предварительно объявлены, их имена могут быть объявлены без указания перечислителей:
enum Color; // Ошибка!
enum class Color; // OK
Это заблуждение. В С++11 перечисления без областей видимости также могут быть объявлены предварительно, но только с помощью небольшой дополнительной работы, которая вытекает из того факта, что каждое перечисление в С++ имеет целочисленный базовый тип (underlying type), который определяется компилятором. Для перечисления без области видимости наподобие Color
enum Color { black, white, red };
компилятор может выбрать в качестве базового типа char
, так как он должен представить всего лишь три значения. Однако некоторые перечисления имеют куда больший диапазон значений, например:
enum Status { good = 0,
failed = 1,
incomplete = 100,
corrupt = 200,
indeterminate = 0xFFFFFFFF
};
Здесь должны быть представлены значения в диапазоне от 0
до 0xFFFFFFFF
. За исключением необычных машин (где char
состоит как минимум из 32 битов), компилятор выберет для предоставления значений Status
целочисленный тип, больший, чем char
.
Для эффективного использования памяти компиляторы часто выбирают наименьший базовый тип, которого достаточно для представления значений перечислителей. В некоторых случаях, когда компиляторы выполняют оптимизацию по скорости, а не по размеру, они могут выбрать не наименьший допустимый тип, но при этом они, определенно, захотят иметь возможность оптимизации размера. Для этого С++98 поддерживает только определения enum
(в которых перечислены все значения); объявления enum
не разрешены. Это позволяет компиляторам выбирать базовый тип для каждого enum
до его использования.
Интервал:
Закладка: