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

Тут можно читать онлайн Скотт Мейерс - Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - бесплатно полную версию книги (целиком) без сокращений. Жанр: comp-programming, издательство Вильямс, год 2016. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14
  • Автор:
  • Жанр:
  • Издательство:
    Вильямс
  • Год:
    2016
  • Город:
    Москва
  • ISBN:
    978-5-8459-2000-3
  • Рейтинг:
    3/5. Голосов: 11
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 60
    • 1
    • 2
    • 3
    • 4
    • 5

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

Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - описание и краткое содержание, автор Скотт Мейерс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru
Эффективный и современный С++
В книге рассматриваются следующие темы. Освоение С++11 и С++14 — это больше, чем просто ознакомление с вводимыми этими стандартами возможностями (например, объявлениями типов
, семантикой перемещения, лямбда-выражениями или поддержкой многопоточности). Вопрос в том, как использовать их эффективно, чтобы создаваемые программы были корректны, эффективны и переносимы, а также чтобы их легко можно было сопровождать. Именно этим вопросам и посвящена данная книга, описывающая создание по-настоящему хорошего программного обеспечения с использованием C++11 и С++14 — т.е. с использованием современного С++.
■ Преимущества и недостатки инициализации с помощью фигурных скобок, спецификации
, прямой передачи и функций
интеллектуальных указателей
■ Связь между
,
, rvalue-ссылками и универсальными ссылками
■ Методы написания понятных, корректных,
лямбда-выражений
■ Чем
отличается от
, как они используются и как соотносятся с API параллельных вычислений С++
■ Какие из лучших методов “старого” программирования на С++ (т.е. С++98) должны быть пересмотрены при работе с современным С++
Более чем 20 лет книги
серии
являются критерием уровня книг по программированию на С++. Понятное пояснение сложного технического материала принесло ему всемирную известность. Он всегда самый желанный гость на международных конференциях, а его услуги консультанта широко востребованы во всем мире.
Скотт Мейерс Эффективный и современный С++, После изучения основ С++ я перешел к изучению того, как применять С++ в промышленном программировании, с помощью серии книг Скотта Мейерса Эффективный С++. Эффективный и современный С++ — наиболее важная из книг серии, предлагающая ключевые рекомендации, стили и идиомы, позволяющие эффективно использовать современный С++. Вы еще не купили эту книгу? Сделайте это прямо сейчас. Герб Саттер,
глава Комитета ISO по стандартизации С++, специалист в области архитектуры программного обеспечения на С++ в Microsoft

Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - читать онлайн бесплатно полную версию (весь текст целиком)

Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - читать книгу онлайн бесплатно, автор Скотт Мейерс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

В качестве второго примера применения std::bindдля эмуляции перемещающего захвата рассмотрим пример кода С++ 14, который мы видели ранее и который создает std::unique_ptrв замыкании:

auto func = [ pw = std::make_unique()] // Как и ранее,

{ return pw->isValidated() // создает pw

&& pw->isArchived(); }; // в замыкании

А вот как выглядит его эмуляция на С++11:

auto func = std::bind(

[]( const std::unique_ptr& pw)

{ return pw->isValidated()

&& pw->isArchived(); },

std::make_unique()

);

Забавно, что я показываю, как использовать std::bindдля обхода ограничений лямбда-выражений в С++11, поскольку в разделе 6.4 я выступаю как сторонник применения лямбда-выражений вместо std::bind. Однако в данном разделе поясняется, что в С++11 имеются ситуации, когда может пригодиться std::bind, и это одна из них. (В С++14 такие возможности, как инициализирующий захват и параметры auto, устраняют такие ситуации.)

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

• Для перемещения объектов в замыкания используется инициализирующий захват С++14.

• В С++11 инициализирующий захват эмулируется с помощью написания классов вручную или применения std::bind.

6.3. Используйте параметры decltypeдля auto&&для передачи с помощью std::forward

Одной из самых интересных возможностей С++14 являются обобщенные лямбда-выражения — лямбда-выражения, в спецификации параметров которых используется ключевое слово auto. Реализация этой возможности проста: operator()в классе замыкания лямбда-выражения является шаблоном. Например, для лямбда-выражения

auto f = []( autox){ return normalize(x); };

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

class SomeCompilerGeneratedClassName {

public:

template // См. возвращаемый тип auto

auto operator()( Tх) const // в разделе 1.3

{ return normalize(x); }

… // Прочая функциональность

}; // класса замыкания

В этом примере единственное, что делает лямбда-выражение с параметром x, — это передает его функции normalize. Если normalizeрассматривает значения lvalue не так, как значения rvalue, это лямбда-выражение написано некорректно, поскольку оно всегда передает функции normalizelvalue (параметр x), даже если переданный в лямбда-выражение аргумент представляет собой rvalue.

Корректным способом написания лямбда-выражения является прямая передача xв normalize. Это требует внесения в код двух изменений. Во-первых, xдолжен быть универсальной ссылкой (см. раздел 5.2), а во-вторых, он должен передаваться в normalizeс использованием std::forward(см. раздел 5.3). Концептуально это требует тривиальных изменений:

auto f = [](auto &&x)

{ return normalize( std::forward (x )); };

Однако между концепцией и реализацией стоит вопрос о том, какой тип передавать в std::forward, т.e. вопрос определения того, что должно находиться там, где я написал “ ???”.

Обычно, применяя прямую передачу, вы находитесь в шаблонной функции, принимающей параметр типа T, так что вам надо просто написать std::forward. В обобщенном лямбда-выражении такой параметр типа Tвам недоступен. Имеется Tв шаблонизированном операторе operator()в классе замыкания, сгенерированном лямбда-выражением, но сослаться на него из лямбда-выражения невозможно, так что это никак не помогает.

В разделе 5.6. поясняется, что если lvalue-apryмeнт передается параметру, являющемуся универсальной ссылкой, то типом этого параметра становится lvalue-ссылка. Если же передается rvalue, параметр становится rvalue-ссылкой. Это означает, что вне лямбда-выражения мы можем определить, является ли переданный аргумент lvalue или rvalue, рассматривая тип параметра x. Ключевое слово decltypeдает нам возможность сделать это (см. раздел 1.3). Если было передано lvalue, decltype(x)даст тип, являющийся lvalue-ссылкой. Если же было передано rvalue, decltype(x)даст тип, являющийся rvalue-ссылкой.

В разделе 5.6 поясняется также, что при вызове std::forwardсоглашения требуют, чтобы для указания lvalue аргументом типа была lvalue-ссылка, а для указания rvalue — тип, не являющийся ссылкой. В нашем лямбда-выражении, если x привязан к lvalue, decltype(x)даст lvalue-ссылку. Это отвечает соглашению. Однако, если xпривязан к rvalue, decltype(x)вместо типа, не являющегося ссылкой, даст rvalue-ссылку. Но взглянем на пример реализации std::forwardв С++14 из раздела 5.6:

template // В пространстве

T&& forward(remove_reference_t& param) // имен std

{

return static_cast(param);

}

Если клиентский код хочет выполнить прямую передачу rvalue типа Widget, он обычно инстанцирует std::forwardтипом Widget(т.e. типом, не являющимся ссылочным), и шаблон std::forwardдает следующую функцию:

Widget&& forward( Widget& param) // Инстанцирование для

{ // std::forward, когда

return static_cast< Widget&&>(param); // T является Widget

}

Но рассмотрим, что произойдет, если код клиента намерен выполнить прямую передачу того же самого rvalue типа Widget, но вместо следования соглашению об определении Tкак не ссылочного типа определит его как rvalue-ссылку, т.e. рассмотрим, что случится, если Tопределен как Widget&&. После начального инстанцирования std::forwardи применения std::remove_reference_t, но до свертывания ссылок (еще раз обратитесь к разделу 5.6) std::forwardбудет выглядеть следующим образом:

Widget&&&& forward( Widget&param) // Инстанцирование

{ // std::forward при

return static_cast< Widget&&&&>(param); // T, равном Widget&&

} // (до сворачивания ссылок)

Применение правила сворачивания ссылок о том, что rvalue-ссылка на rvalue-ссылку становится одинарной rvalue-ссылкой, приводит к следующему инстанцированию:

Widget&& forward(Widget& param) // Инстанцирование

{ // std::forward при

return static_cast(param); // T, равном Widget&&

} // (после сворачивания ссылок)

Если вы сравните это инстанцирование с инстанцированием, получающимся в результате вызова std::forwardс T, равным Widget, то вы увидите, что они идентичны. Это означает, что инстанцирование std::forwardтипом, представляющим собой rvalue-ссылку, дает тот же результат, что и инстанцирование типом, не являющимся ссылочным.

Это чудесная новость, так как decltype(x)дает rvalue-ссылку, когда в качестве аргумента для параметра x нашего лямбда-выражения передается rvalue. Выше мы установили, что, когда в наше лямбда-выражение передается lvalue, decltype(х)дает соответствующий соглашению тип для передачи в std::forward, и теперь мы понимаем, что для rvalue decltype(x)дает тип для передачи std::forward, который не соответствует соглашению, но тем не менее приводит к тому же результату, что и тип, соответствующий соглашению. Так что как для lvalue, так и для rvalue передача decltype(x) в std::forwardдает нам желаемый результат. Следовательно, наше лямбда-выражение с прямой передачей может быть записано следующим образом:

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Скотт Мейерс читать все книги автора по порядку

Скотт Мейерс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14, автор: Скотт Мейерс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x