Упражнение 6.25. Напишите функцию main()
, получающую два аргумента. Конкатенируйте предоставленные аргументы и выведите полученную строку.
Упражнение 6.26. Напишите программу, которая способна получать параметры командной строки, описанные в этом разделе. Отобразите значения аргументов, переданных функции main()
.
6.2.6. Функции с переменным количеством параметров
Иногда количество аргументов, подлежащих передаче функции, неизвестно заранее. Например, могла бы понадобиться функция, выводящая сообщения об ошибках, созданные нашей программой. Нам хотелось бы использовать одну функцию, чтобы выводить эти сообщения единообразным способом. Однако различные вызовы этой функции могли бы передавать разные аргументы, соответствующие разным видам сообщений об ошибках.
Новый стандарт предоставляет два основных способа создания функций, получающих переменное количество аргументов: если у всех аргументов тот же тип, можно передать объект библиотечного класса initializer_list
. Если типы аргументов разные, можно написать функцию специального вида, известную как
В языке С++ есть также специальный тип параметра, многоточие, применяющийся для передачи переменного количества аргументов. Мы кратко рассмотрим параметры в виде многоточия далее в этом разделе. Но следует заметить, что это средство обычно используют только в программах, которые должны взаимодействовать с функциями С.
initializer_list
initializer_list
. Тип initializer_list
— это библиотечный класс, который представляет собой массив (см. раздел 3.5) значений определенного типа. Этот тип определен в заголовке initializer_list
. Операции, предоставляемые классом initializer_list
, перечислены в табл. 6.1.
Таблица 6.1. Операции, предоставляемые классом initializer_list
initializer_list | Инициализация по умолчанию; пустой список элементов типа T |
initializer_list | lst имеет столько элементов, сколько инициализаторов; элементы являются копиями соответствующих инициализаторов. Элементы списка — константы |
lst2(lst) lst2 = lst | Копирование или присвоение объекта класса. initializer_list не копирует элементы в списке. После копирования первоисточник и копия совместно используют элементы |
lst.size() | Количество элементов в списке |
lst.begin() lst.end() | Возвращает указатель на первый и следующий после последнего элементы lst |
Подобно типу vector
, тип initializer_list
является шаблоном (см. раздел 3.3). При определении объекта класса initializer_list
следует указать тип элементов, которые будет содержать список:
initializer_list
initializer_list
В отличие от вектора, элементы списка initializer_list
всегда константы; нет никакого способа изменить значение его элементов.
Функцию отображения сообщений об ошибках с переменным количеством аргументов можно написать следующим образом:
void error_msg(initializer_list
for (auto beg = il.begin(); beg != il.end(); ++beg)
cout << *beg << " ";
cout << endl;
}
Методы begin()
и end()
объектов класса initializer_list
аналогичны таковым у класса vector
(см. раздел 3.4.1). Метод begin()
предоставляет указатель на первый элемент списка, а метод end()
— на следующий элемент после последнего. Наша функция инициализирует переменную beg
указателем на первый элемент и перебирает все элементы списка initializer_list
. В теле цикла осуществляется обращение к значению beg
, что позволяет получить доступ к текущему элементу и вывести его значение.
При передаче последовательности значений в параметре типа initializer_list
последовательность следует заключить в фигурные скобки:
//