На этом шаге мы рассмотрим различные способы инициализации контейнера.
Любой контейнерный класс содержит конструктор по умолчанию, копирующий конструктор и деструктор. Кроме того, предусмотрена возможность инициализации контейнера элементами из заданного интервала. Соответствующий конструктор позволяет инициализировать контейнер элементами другого контейнера, массива или просто элементами, прочитанными из стандартного входного потока данных. Такие конструкторы оформляются а виде шаблонных функций класса, поэтому различия возможны не только в типе контейнера, но и в типе элементов (при условии автоматического преобразования исходного типа элемента к итоговому типу). Несколько примеров инициализации:
std::list<int> l; // l - связанный список int // Копирование всех элементов списка в вектор с приведением к типу float std::vector<float> c(l.begin(),l.end());
int аггау[] = { 2, 3, 17, 33, 45, 77 }; // Копирование всех элементов массива в множество std::set<int> c(array,array+sizeof(array)/sizeof(array[0]));
// Чтение элементов типа int в дек из стандартного ввода
std::deque<int> c((std::istream_iterator<int>(std::cin)),
(std::istrean_iterator<int>()));
He забудьте заключить аргументы инициализатора в дополнительные круглые скобки. Без них выражение работает совсем не так, как предполагалось. Скорее всего, все кончится странными предупреждениями или ошибками в следующих командах. Рассмотрим ту же команду без дополнительных круглых скобок:
std::deque<int> c(std::istream_iterator<int>(std::cin), std::istream_iterator<int>());
В этом варианте c объявляет функцию, возвращающую тип deque<int>. Ее первый параметр cin относится к типу istream_iterator<int>, а второй безымянный параметр - к типу "функция, вызываемая без аргументов и возвращающая istream_iterator<int>". Эта конструкция синтаксически действительна и как объявление, и как выражение. Следовательно, в соответствии с правилами языка она интерпретируется как объявление. При введении дополнительных круглых скобок инициализатор перестает соответствовать синтаксису объявления.
В принципе эта методика также применяется при присваивании или вставке элементов из другого интервала. Однако в этих операциях интерфейс либо отличается наличием дополнительных аргументов, либо поддерживается не всеми контейнерными классами.
На следующем шаге мы рассмотрим операции проверки размера.