Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
template void f(const T*);
template void g(T);
template void g(T*);
int i = 42, *p = &i;
const int ci = 0, *p2 = &ci;
g(42); g(p); g(ci); g(p2);
f(42); f(p); f(ci); f(p2);
Упражнение 16.50. Определите функции из предыдущего упражнения так, чтобы они выводили идентификационное сообщение. Выполните код этого упражнения. Если вызовы ведут себя не так, как ожидалось, выясните почему.
16.4. Шаблоны с переменным количеством аргументов
Шаблон с переменным количеством аргументов (variadic template) — это шаблон функции или класса, способный получать переменное количество параметров. Набор таких параметров называется пакетом параметров (parameter pack). Есть два вида пакетов параметров: пакет параметров шаблона (template parameter pack), представляющий любое количество параметров шаблона, и пакет параметров функции (function parameter pack), представляющий любое количество параметров функции.
Для указания, что шаблону или функции представлен пакет параметров, используется многоточие. В списке параметров шаблона синтаксис class...
или typename...
означает, что следующий параметр представляет список любого количества типов; имя типа, сопровождаемое многоточием, представляет список из любого количества параметров значения заданного типа. Параметр в списке параметров функции, типом которого является пакет параметров шаблона, представляет собой пакет параметров функции. Например:
// Args - это пакет параметров шаблона; rest - пакет параметров функции
// Args представляет любое количество параметров типа шаблона
// rest представляет любое количество параметров функции
template
void foo(const T &t, const Args& ... rest);
Этот код объявляет, что fоо()
— это функция с переменным количеством аргументов, у которой один параметр типа по имени T
и пакет параметров шаблона по имени Args
. Этот пакет представляет любое количество дополнительных параметров типа. В списке параметров функции foo()
один параметр типа const&
для любого типа переданного параметром Т
и пакет параметров функции rest
. Этот пакет представляет любое количество параметров функции.
Как обычно, компилятор выводит типы параметра шаблона из аргументов функции. Для шаблона с переменным количеством аргументов компилятор также выводит количество параметров в пакете. Рассмотрим, например, следующие вызовы:
int i = 0; double d = 3.14; string s = "how now brown cow";
foo(i, s, 42, d); // три параметра в пакете
foo(s, 42, "hi"); // два параметра в пакете
foo(d, s); // один параметр в пакете
foo("hi"); // пустой пакет
Компилятор создаст четыре разных экземпляра функции fоо()
:
void foo(const int&, const string&, const int&, const double&);
void foo(const string&, const int&, const char[3]&);
void foo(const double&, const string&);
void foo(const char[3]&);
В каждом случае тип T
выводится из типа первого аргумента. Остальные аргументы (если они есть) представляют количество и типы дополнительных аргументов функции.
sizeof...
Когда необходимо узнать, сколько элементов находится в пакете, можно использовать оператор
sizeof...
. Как и оператор sizeof
(см. раздел 4.9), оператор sizeof...
возвращает константное выражение (см. раздел 2.4.4) и не вычисляет свой аргумент:
template void g(Args ... args) {
cout << sizeof...(Args) << endl; // количество параметров типа
cout << sizeof...(args) << endl; // количество параметров функции
}
Упражнение 16.51. Определите, что возвратят операторы sizeof...(Args)
и sizeof...(rest)
для каждого вызова функции foo()
в этом разделе.
Упражнение 16.52. Напишите программу, проверяющую ответы на предыдущий вопрос.
16.4.1. Шаблоны функции с переменным количеством аргументов
В разделе 6.2.6 упоминалось, что для определения функции, способной получать переменное количество аргументов, можно использовать класс initializer_list
. Однако у аргументов должен быть одинаковый тип (или типы, преобразуемые в общий тип). Функции с переменным количеством аргументов используются тогда, когда не известно ни количество, ни типы аргументов. Для примера определим функцию, подобную прежней функции error_msg()
, только на сей раз обеспечим и изменение типов аргумента. Начнем с определения функции print()
с переменным количеством аргументов, которая выводит содержимое заданного списка аргументов в указанный поток.
Функции с переменным количеством аргументов зачастую рекурсивны (см. раздел 6.3.2). Первый вызов обрабатывает первый аргумент в пакете и вызывает себя для остальных аргументов. Новая функция print()
будет работать таким же образом — каждый вызов выводит свой второй аргумент в поток, обозначенный первым аргументом. Для остановки рекурсии следует определить также обычную функцию print()
, которая получает поток и объект:
// Функция для завершения рекурсии и вывода последнего элемента
// ее следует объявить перед определением версией print() с переменным
// количеством аргументов
template
ostream &print(ostream &os, const T &t) {
return os << t; // нет разделителя после последнего элемента в пакете
}
// эта версия print() будет вызвана для всех элементов в пакете, кроме
// последнего
template
ostream &print(ostream &os, const T &t, const Args&... rest) {
os << t << ", "; // выводит первый аргумент
return print(os, rest...); // рекурсивный вызов; вывод других
// аргументов
}
Первая версия функции print()
останавливает рекурсию и выводит последний аргумент в начальном вызове функции print()
. Вторая версия, с переменным количеством аргументов, выводит аргумент, связанный с t
, и вызывает себя для вывода остальных значений в пакете параметров функции.
Ключевая часть — вызов функции print()
в функции с переменным количеством аргументов:
return print(os, rest...); // рекурсивный вызов; вывод других
// аргументов
Версия функции print()
с переменным количеством аргументов получает три параметра: ostream&
, const T&
и пакет параметров. Но в этом вызове передаются только два аргумента. В результате первый аргумент в пакете rest
привязывается к t
. Остальные аргументы в пакете rest
формируют пакет параметров для следующего вызова функции print()
. Таким образом, при каждом вызове первый аргумент удаляется из пакета и становится аргументом, связанным с t. Соответственно, получаем:
Интервал:
Закладка: