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

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

и >end, но не были добавлены >cbegin, >cend, >rbegin, >rend, >crbegin и >crend. С++ 14 исправляет это упущение.

Если вы используете С++11, хотите написать максимально обобщенный код и ни одна из используемых вами библиотек не предоставляет отсутствующие шаблоны для >cbegin и подобных функций, не являющихся шаблонами, можете легко написать собственные реализации. Например, вот как выглядит реализация функции >cbegin, не являющейся членом:

>template

>auto cbegin(const С& container)->decltype(std::begin(container)) {

> return std::begin(container); // См. пояснения ниже

>}

Вы удивлены тем, что эта функция >cbegin не вызывает функцию-член >cbegin, не так ли? Я тоже был удивлен. Но давайте подумаем логически. Этот шаблон >cbegin принимает аргументы любого типа, представляющего контейнерообразную структуру данных С, и обращается к этому аргументу через ссылку на константный объект >container. Если С — обычный тип контейнера (например, >std::vector), то >container будет ссылкой на >const-версию этого контейнера (например, >const std::vector&). Вызов функции >begin, не являющейся членом (и предоставленной С++11), для константного контейнера дает константный итератор >const_iterator, и именно этот итератор и возвращает наш шаблон. Преимущества такой реализации в том, что она работает даже для контейнеров, которые предоставляют функцию-член >begin (которую функция С++11 >begin, не являющаяся членом, вызывает для контейнеров), но не имеют функции-члена >cbegin. Таким образом, вы можете использовать эту свободную функцию >cbegin с контейнерами, поддерживающими единственную функцию-член >begin.

Этот шаблон работает и в случае, когда С представляет собой встроенный массив. При этом >container становится ссылкой на константный массив. C++11 предоставляет для массивов специализированную версию функции >begin, не являющейся членом, которая возвращает указатель на первый элемент массива. Элементы константного массива являются константами, так что указатель, который возвращает свободная функция >begin, возвращает для константного массива указатель на константу, который фактически и является >const_iterator для массива. (Для понимания, как специализировать шаблон для встроенных массивов, обратитесь к обсуждению в разделе 1.1 вывода типов в шаблонах, которые получают в качестве параметров ссылки на массивы.)

Но вернемся к основам. Суть этого раздела заключается в том, чтобы призвать вас использовать >const_iterator везде, где возможно. Фундаментальный мотив для этого — применение >const всегда, когда это имеет смысл — существовал и до С++11, но в С++98 этот принцип при работе с итераторами был непрактичным. В С++11 это сугубо практический совет, а в С++14 к тому же “доведены до ума” некоторые мелочи, остававшиеся незавершенными в С++11.

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

• Предпочитайте использовать >const_iterator вместо >iterator там, где это можно.

• В максимально обобщенном коде предпочтительно использовать версии функций >begin, >end, >rbegin и прочих, не являющиеся членами.

3.8. Если функции не генерируют исключений, объявляйте их как >noexcept

В С++98 спецификации исключений были довольно темпераментными созданиями. От вас требовалось собрать информацию обо всех типах исключений, которые могла генерировать функция, так что при изменении реализации функции могла потребовать изменения и спецификация исключений. Изменение спецификации исключения могло нарушить клиентский код, так как вызывающий код мог зависеть от исходной спецификации исключений. Компиляторы обычно не предлагали никакой помощи в поддержании согласованности между реализациями функций, спецификациями исключений и клиентским кодом. Большинство программистов в конечном итоге сочло, что спецификации исключений в С++98 не стоят затрачиваемых на них усилий и ими лучше не пользоваться вовсе. Во время работы над С++11 было достигнуто согласие, что действительно важная информация о поведении функций в смысле исключений — это информация, может ли вообще такое исключение быть сгенерировано. Либо функция может генерировать исключение, либо гарантируется, что это невозможно. Именно эта дихотомия лежит в основе спецификаций исключений С++11, которые, по сути, заменили спецификации исключений С++98. (Спецификации исключений в стиле С++98 остаются корректными, но не рекомендуются к употреблению.) В С++11 безусловный модификатор >noexcept применяется к функциям, которые гарантированно не могут генерировать исключения.

Должна ли функция быть объявлена таким образом — вопрос проектирования интерфейса. Поведение генерирующих исключения функций представляет большой интерес для клиентов. Вызывающий код может запросить статус >noexcept функции, и результат этого запроса может повлиять на безопасность в смысле исключений или эффективность вызывающего кода. Таким образом, является ли функция объявленной как >noexcept, представляет собой столь же важную часть информации, как и является ли функция-член объявленной как >const. Отсутствие объявления функции как >noexcept, когда вы точно знаете, что она не в состоянии генерировать исключения, — не более чем просто плохая спецификация интерфейса.


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