Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Списки инициализации






Давайте рассмотрим следующий пример:

vector< double> v = { 1, 2, 3.456, 99.99 }; list< pair< string, string> > languages = { {" Nygaard", " Simula" }, {" Richards", " BCPL" }, {" Ritchie", " C" } }; map< vector< string>, vector< int> > years = { { {" Maurice", " Vincent", " Wilkes" }, {1913, 1945, 1951, 1967, 2000} }, { {" Martin", " Ritchards" } {1982, 2003, 2007} }, { {" David", " John", " Wheeler" }, {1927, 1947, 1951, 2004} } };

 

Теперь списки инициализации могут использоваться не только для массивов. Механизмом доступа к {}-списку является функция (в большинстве случаев конструктор), принимающая в качестве аргумента std:: initializer_list< T>. Например:

void f(initializer_list< int>); f({1, 2}); f({23, 345, 4567, 56789}); f({}); // пустой список f{1, 2}; // ошибка: пропущен вызов метода () years.insert({{" Bjarne", " Stroustrup" }, {1950, 1975, 1985}});

 

Список инициализации может быть произвольной длины, но должен быть однородным (все элементы должны быть такого же типа, что указан в качестве параметра шаблона (std:: initializer_list< T>), или же должны преобразовываться к T).

Контейнер может реализовывать конструктор, принимающий список инициализации следующим образом:

template< class E> class vector { public: // конструктор, принимающий список инициализации vector (std:: initializer_list< E> s) { // выделить нужное количество памяти reserve(s.size()); // проинициализировать элементы в диапазонеelem[0: s.size())) uninitialized_copy(s.begin(), s.end(), elem); sz = s.size(); // установить размер вектора } //... как и было... };

 

Различия между непосредственной инициализацией и инициализацией копирования сохраняется и в случае использования списков инициализации, но в этом случае разница менее существенна. Например, у std:: vector есть явный (explicit) конструктор, принимающий int и принимающий список инициализации:

// ОК: v1 содержит 7 элементов vector< double> v1(7); // ошибка: отсутствует преобразование из int к vector v1 = 9; // ошибка: отсутствует преобразования из int к vector vector< double> v2 = 9; void f(const vector< double> &); // ошибка: отсутствует преобразование из int к vector f(9); // ОК: v1 содержит 1 элемент (со значением 7) vector< double> v1{7}; // ОК v1 теперь содержит 1 элемент (со значением 9) v1 = {9}; // ОК: v2 содержит 1 элемент (со значением 9) vector< double> v2 = {9}; // ОК: f вызывается со списком { 9 } f({9}); vector< vector< double> > vs = { // ОК: вызов явного конструктора (10 элементов) vector< double> (10), // ОК: вызов явного конструктора (1 элемент со значением 10) vector< double> {10}, // ошибка: конструктор класса vector явный (explicit) 10 };

 

Функция может использовать initializer_list как неизменяемую последовательность. Например:

void f(initializer_list< int> args) { for (auto p=args.begin(); p! =args.end(); ++p) cout < < *p < < " \n"; }

 

Конструктор, принимающий единственный аргумент типа std:: initializer_list называется конструктором со списком инициализации (initializer-list constructor).

Контейнеры стандартной библиотеки, такие как string и regex содержат конструкторы, операторы присваивания и т.д., принимающие списки инициализации. Списки инициализации могут использоваться в качестве диапазонов значений, например, в range-for операторе.

См. также:

  • the C++ draft 8.5.4 List-initialization [dcl.init.list]
  • [N1890=05-0150 ] Bjarne Stroustrup and Gabriel Dos Reis: Initialization and initializers (an overview of initialization-related problems with suggested solutions).
  • [N1919=05-0179] Bjarne Stroustrup and Gabriel Dos Reis: Initializer lists.
  • [N2215=07-0075] Bjarne Stroustrup and Gabriel Dos Reis: Initializer lists (Rev. 3).
  • [N2640=08-0150] Jason Merrill and Daveed Vandevoorde: Initializer Lists -- Alternative Mechanism and Rationale (v. 2) (final proposal).

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.