Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
16.2.5. Дедукция аргумента шаблона и ссылки
Чтобы лучше понять дедукцию типа, рассмотрим такой вызов функции где параметр функции pявляется ссылкой на параметр типа шаблона T:
template void f(Т &p);
Обратите внимание на два момента: здесь применяются обычные правила привязки ссылок; и спецификаторы constздесь нижнего уровня, а не верхнего.
Когда параметр функции представляет собой обычную ссылку (l-значение) на параметр типа шаблона (т.е. имеющего форму T&), правила привязки гласят, что передавать можно только l-значения (например, переменная или выражение, возвращающее ссылочный тип). Этот аргумент может быть или не быть константным. Если аргумент будет константой, то тип Тбудет выведен как константный:
template void f1(Т&); // аргумент должен быть l-значением
// вызовы f1() используют ссылочный тип аргумента как тип параметра
// шаблона
f1(i); // i - это int; параметр шаблона Т - это int
f1(ci); // ci - это const int; параметр шаблона Т - это const int
f1(5); // ошибка: аргумент ссылочного параметра
// должен быть l-значением
Если параметр функции имеет тип const Т&, обычные правила привязки гласят, что можно передать любой вид аргумента — объект (константный или нет), временный объект или литеральное значение. Когда сам параметр функции является константой, выведенный для параметра Ттип не будет константным типом. Константность является частью типа параметра функции, и поэтому она не становится также частью типа параметра шаблона:
template void f2(const T&); // может получать r-значения
// параметр в f2() - это const & const в аргументе неуместен
// в каждом из этих трех вызовов параметр функции f2() выводится
// как const int&
f2(i); // i - это int; параметр шаблона Т - это int
f2(ci); // ci - это const int, но параметр шаблона T - это int
f2(5); // параметр const & может быть привязан к r-значению;
// Т - это int
Когда параметр функции является ссылкой на r-значение (см. раздел 13.6.1), т.е. имеет форму Т&&, обычные правила привязки гласят, что этому параметру можно передать r-значение. При этом дедукция типа ведет себя таким же образом, как дедукция обычного ссылочного параметра функции на l-значение. Выведенный тип для параметра Т— это тип r-значения:
template void f3(T&&);
f3(42); // аргумент - это r-значение типа int; параметр
// шаблона Т - это int
Предположим, что iявляется объектом типа int. Можно подумать, что такой вызов, как f3(i), будет недопустим. В конце концов, i— это l-значение, а ссылку на r-значение обычно нельзя связать с l-значением. Однако язык определяет два исключения из обычных правил привязки, которые позволяют это. На этих исключениях из правил основан принцип работы таких библиотечных функций, как move().
Первое исключение относится к дедукции типа для ссылочного параметра на r-значение. Когда l-значение (например, i) передается параметру функции, являющемуся ссылкой на r-значение на параметр типа шаблона (например, Т&&), компилятор выводит параметр типа шаблона как тип ссылки на l-значение аргумента. Поэтому, когда происходит вызов f3(i), компилятор выводит тип Ткак int&, а не int.
Выведение типа Ткак int&, казалось бы, означает, что параметр функции f3()будет ссылкой на r-значение типа int&. Обычно нельзя (непосредственно) определить ссылку на ссылку (см. раздел 2.3.1). Но это можно сделать косвенно, через псевдоним типа (см. раздел 2.5.1) или через параметр типа шаблона.
В таких ситуациях проявляется второе исключение из обычных правил привязки: если косвенно создать ссылку на ссылку, то эти ссылки " сворачиваются " (collapse). Во всех случаях кроме одного сворачивание ссылок формирует обычный тип ссылки на l-значение. Новый стандарт дополняет правила свертывания, включая ссылки на r-значение. Ссылки сворачиваются, формируя ссылку на r-значение только в специфическом случае ссылки на r-значение на ссылку на r-значение. Таким образом, для данного типа X:
• X& &, X& &&и X&& &сворачиваются в тип X&.
• Тип X&& &&сворачивается в тип X&&.
Сворачивание ссылок применимо только тогда, когда ссылка на ссылку создается косвенно, как в псевдониме типа или параметре шаблона.
Комбинация правил свертывания ссылок и специального правила дедукции типа для ссылочных на r-значения параметров означает, что можно вызвать функцию f3()для l-значения. Когда параметру функции f3()(ссылке на r-значение) передается l-значение, компилятор выведет тип Tкак тип ссылки на l-значение:
f3(i); // аргумент - это l-значение; параметр Т шаблона - это int&
f3(ci); // аргумент - это l-значение;
// параметр Т шаблона - это const int&
Когда параметр Tшаблона выводится как ссылочный тип, правило свертывания гласит, что параметр функции T&&сворачивается в тип ссылки на l-значение. Например, результирующий экземпляр для вызова f3(i)получится примерно таким:
// недопустимый код, приведен только для примера
void f3(int& &&); // когда T - это int&, параметр
// функции - это int& &&
Параметр функции f3()— это Т&&, а T— это int&, таким образом, Т&&будет int& &&, что сворачивается в int&. Таким образом, даже при том, что формой параметра функции f3()будет ссылка на r-значение (т.е. T&&), этот вызов создаст экземпляр функции f3()с типом ссылки на l-значение (т.е. int&):
void f3(int&); // когда T - это int&, параметр функции
// сворачивается в int&
У этих правил есть два важных следствия.
• Параметр функции, являющийся ссылкой на r-значение для параметра типа шаблона (например, Т&&), может быть связан с l-значением.
• Если аргумент будет l-значением, то выведенный тип аргумента шаблона будет типом ссылки на l-значение, и экземпляр параметра функции будет создан как (обычный) параметр ссылки на l-значение ( Т&).
Стоит также обратить внимание на то, что параметру функции Т&&косвенно можно передать аргумент любого типа. Параметр такого типа может использоваться с r-значениями, а, как было продемонстрировано только что, также и с l-значениями.
Интервал:
Закладка: