Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - [12]
для некоторого неизвестного >Т
, вывод типа шаблона сможет определить, чем является >Т
:
>template
>void f(std::initializer_list<T> initList);
>f({ 11, 23, 9 }); // Вывод int в качестве типа Т, а тип
> // initList - std::initializer_list
Таким образом, единственное реальное различие между выводом типа >auto
и выводом типа шаблона заключается в том, что >auto
предполагает, что инициализатор в фигурных скобках представляет собой >std::initializer_list
, в то время как вывод типа шаблона этого не делает.
Вы можете удивиться, почему вывод типа >auto
имеет специальное правило для инициализаторов в фигурных скобках, в то время как вывод типа шаблона такого правила не имеет. Но я и сам удивлен. Увы, я не в состоянии найти убедительное объяснение. Но “закон есть закон”, и это означает, что вы должны помнить, что если вы объявляете переменную с использованием ключевого слова >auto
и инициализируете ее с помощью инициализатора в фигурных скобках, то выводимым типом всегда будет >std::initializer_list
. Особенно важно иметь это в виду, если вы приверженец философии унифицированной инициализации — заключения инициализирующих значений в фигурные скобки как само собой разумеющегося стиля. Классической ошибкой в С++11 является случайное объявление переменной >std::initializer_list
там, где вы намеревались объявить нечто иное. Эта ловушка является одной из причин, по которым некоторые разработчики используют фигурные скобки в инициализаторах только тогда, когда обязаны это делать. (Когда именно вы обязаны так поступать, мы рассмотрим в разделе 3.1.)
Что касается С++ 11, то на этом история заканчивается, но для С++14 это еще не конец. С++14 допускает применение >auto
для указания того, что возвращаемый тип функции должен быть выведен (см. раздел 1.3), а кроме того, лямбда-выражения С++ 14 могут использовать >auto
в объявлениях параметров. Однако такое применение >auto
использует вывод типа шаблона, а не вывод типа >auto
. Таким образом, функция с возвращаемым типом >auto
, которая возвращает инициализатор в фигурных скобках, компилироваться не будет:
>auto createInitList() {
> return { 1, 2, 3 }; // Ошибка: невозможно вывести
>} // тип для { 1, 2, 3 }
То же самое справедливо и тогда, когда >auto
используется в спецификации типа параметра в лямбда-выражении С++14:
>std::vector
>auto resetV =
> [&v](const auto& newValue) { v = newValue; }; // C++14
>resetV({ 1, 2, 3 }); // Ошибка: невозможно вывести
> // тип для { 1, 2, 3 }
• Вывод типа >auto
обычно такой же, как и вывод типа шаблона, но вывод типа >auto
, в отличие от вывода типа шаблона, предполагает, что инициализатор в фигурных скобках представляет >std::initializer_list
.
• >auto
в возвращаемом типе функции или параметре лямбда-выражения влечет применение вывода типа шаблона, а не вывода типа >auto
.
1.3. Знакомство с >decltype
>decltype
— создание странное. Для данного имени или выражения >decltype
сообщает вам тип этого имени или выражения. Обычно то, что сообщает >decltype
, — это именно то, что вы предсказываете. Однако иногда он дает результаты, которые заставляют вас чесать в затылке и обращаться к справочникам или сайтам.
Мы начнем с типичных случаев, в которых нет никаких подводных камней. В отличие от того, что происходит в процессе вывода типов для шаблонов и >auto
(см. разделы 1.1 и 1.2), >decltype
обычно попугайничает, возвращая точный тип имени или выражения, которое вы передаете ему:
>const int i = 0; // decltype(i) - const int
>bool f(const Widget& w); // decltype(w) - const Widget&
> // decltype(f) - bool(const Widget&)
>struct Point {
> int x, y; // decltype (Point::x) - int
>}; // decltype(Point::y) – int
>Widget w; // decltype(w) – Widget
>if (f(w)) … // decltype (f(w)) — bool
>template
>class vector {
>public:
> …
> T& operator[](std::size_t index);
>};
>vector
>…
>if (v[0] == 0) …
>// decltype(v[0]) - int&
Видите? Никаких сюрпризов.
Пожалуй, основное применение >decltype
в С++11 — объявление шаблонов функций, в которых возвращаемый тип функции зависит от типов ее параметров. Предположим, например, что мы хотим написать функцию, получающую контейнер, который поддерживает индексацию с помощью квадратных скобок (т.е. с использованием “>[]
”) с индексом, а затем аутентифицирует пользователя перед тем как вернуть результат операции индексации. Возвращаемый тип функции должен быть тем же, что и тип, возвращаемый операцией индексации.
>operator[]
для контейнера объектов типа >Т
обычно возвращает >Т&
. Например, это так в случае >std::deque
и почти всегда — в случае >std::vector
. Однако для >std::vector
оператор >operator[]
не возвращает >bool&
. Вместо этого он возвращает новый объект. Все “почему” и “как” данной ситуации рассматриваются в разделе 2.2, но главное здесь то, что возвращаемый оператором >operator[]
контейнера тип зависит от самого контейнера.
>decltype
упрощает выражение этой зависимости. Вот пример, показывающий применение
В этой книге известный автор Скотт Мейерс раскрывает секреты настоящих мастеров, позволяющие добиться максимальной эффективности при работе с библиотекой STL.Во многих книгах описываются возможности STL, но только в этой рассказано о том, как работать с этой библиотекой. Каждый из 50 советов книги подкреплен анализом и убедительными примерами, поэтому читатель не только узнает, как решать ту или иную задачу, но и когда следует выбирать то или иное решение — и почему именно такое.
Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.