Читаем Язык программирования C++. Пятое издание полностью

Типы последних двух аргументов, наряду со схемой, определяют типы замыкающих параметров. Этот вызов создает следующий экземпляр:

ostream&

print(ostream&, const int&, const strings, const int&);

Второе развертывание происходит в рекурсивном вызове функции print(). В данном случае схема — это имя пакета параметров функции (т.е. rest). Эта схема развертывается в разделяемый запятыми список элементов пакета. Таким образом, этот вызов эквивалентен следующему:

print(os, s, 42);

Концепция развертывания пакета

Развертывание пакета параметров функции print() только разворачивало пакет на его составные части. При развертывании пакета параметров функции возможны и более сложные схемы. Например, можно было бы написать вторую функцию с переменным количеством аргументов, которая вызывает функцию debug_rep() (см. раздел 16.3) для каждого из своих аргументов, а затем вызывает функцию print(), чтобы вывести полученные строки:

// вызвать debug_rep() для каждого аргумента в вызове print()

template

ostream &errorMsg(ostream &os, const Args&... rest) {

 // print(os, debug_rep(a1), debug_rep(a2), ..., debug_rep(an)

 return print(os, debug_rep(rest)...);

}

Вызов функции print() использует схему debug_rep(rest). Эта схема означает, что функцию debug_rep() следует вызвать для каждого элемента в пакете параметров функции rest. Получившийся развернутый пакет будет разделяемым запятыми списком вызовов функции debug_rep(). Таким образом, вызов

errorMsg(cerr, fcnName, code.num(), otherData, "other", item);

выполняется, как будто было написано:

print(cerr, debug_rep(fcnName), debug_rep(code.num()),

            debug_rep(otherData), debug_rep("otherData"),

            debug_rep(item));

Следующая схема, напротив, не была бы откомпилирована:

// передает пакет debug_rep(); print(os, debug_rep(a1, a2, an))

print(os, debug_rep(rest...)); // ошибка: нет функции, соответствующей

                               // вызову

Проблема здесь в том, что пакет rest развернут в вызове функции debug_rep(). Этот вызов выполнился бы так, как будто было написано:

print(cerr, debug_rep(fcnName, code.num(),

            otherData, "otherData", item));

В этом развертывании осуществляется попытка вызова функции debug_rep() со списком из пяти аргументов. Нет никакой версии функции debug_rep(), соответствующей этому вызову. Функция debug_rep() имеет постоянное количество аргументов, и нет никакой ее версии с пятью параметрами.

Схема при развертывании применяется по отдельности к каждому элементу в пакете.

Упражнения раздела 16.4.2

Упражнение 16.56. Напишите и проверьте версию функции errorMsg() с переменным количеством аргументов.

Упражнение 16.57. Сравните свою версию функции errorMsg() с переменным количеством аргументов с функцией error_msg() из раздела 6.2.6. Каковы преимущества и недостатки каждого подхода?

<p><image l:href="#books.png"/>16.4.3. Перенаправление пакетов параметров</p>

По новому стандарту можно использовать шаблоны с переменным количеством аргументов совместно с функцией forward() для написания функций, которые передают свои аргументы неизменными некой другой функции. Чтобы проиллюстрировать такие функции, добавим в класс StrVec (см. раздел 13.5) функцию-член emplace_back(). Такая функция-член библиотечных контейнеров является шаблоном-членом с переменным количеством аргументов (см. раздел 16.1.4), которая использует их для создания элементов непосредственно в области, управляемой контейнером. 

Версия функции emplace_back() для класса StrVec также должна быть с переменным количеством аргументов, поскольку у класса string много конструкторов, которые отличаются своими параметрами.

Поскольку желательно быть в состоянии использовать конструктор перемещения класса string, необходимо будет также сохранять всю информацию о типах аргументов, переданных функции emplace_back().

Как уже упоминалось, сохранение информации типа — двухступенчатый процесс. Во-первых, для сохранения информации типа аргументов параметры функции emplace_back() следует определить как ссылки на r-значение параметра типа шаблона (см. раздел 16.2.7):

class StrVec {

public:

 template void emplace_back(Args&&...);

Перейти на страницу:

Похожие книги

Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript

Данная книга посвящена программированию игр с помощью ActionScript. Здесь вы найдете подробные указания, необходимые для создания самых разных игр – аркад, головоломок, загадок и даже игровых автоматов. В тексте приведены исходные коды программ и детальные, доступно изложенные инструкции. Базовые принципы программирования ActionScript рассматриваются на примере игр, однако вы без труда сможете применить полученные знания и для разработки неигровых проектов, таких как Web-дизайн и реклама. Рекомендации Гэри Розенцвейга помогут вам не только придумывать занимательные игры и размещать их на Web-сайте, но и оптимизировать скорость их работы, а также защищать свои творения от несанкционированного копирования. Представленный в книге код несложно изменить для использования в других программах.Книга предназначена для широкого круга читателей – создателей анимационных роликов, художников-оформителей, программистов и разработчиков Web-сайтов. Издание может также выступать в качестве практического пособия по изучению ActionScript.

Гэри Розенцвейг

Программирование, программы, базы данных / Программирование / Книги по IT
Секреты приложений Google
Секреты приложений Google

Даже продвинутые пользователи Интернета не подозревают о тех огромных возможностях, которые предоставляют сервисы Google. Автор рассказывает о таких «секретах» сервисов, которые просто немедленно хочется использовать! Создавать сайты и презентации, бродить по улочкам Парижа, изучать звездное небо – все это доступно каждому, кто сидит у экрана монитора и имеет доступ в Интернет. Книга научит вас работать с веб-приложениями и тысячекратно увеличить свои возможности с помощью новейших технологий. Она написана легким, доступным языком и не требует от читателя наличия каких-либо специальных знаний. Книга содержит множество примеров, иллюстраций и будет полезна всем, кто не стоит на месте и стремится сделать свою жизнь более насыщенной и интересной.

Денис Балуев , Денис Игоревич Балуев

Программирование, программы, базы данных / Интернет / Программное обеспечение / Книги по IT