Czyli konstrukcja typu vector<int> numbers = {1, 2, 3, 4, 5} wreszcie staje się możliwa!
Szybki przykład
W C++ przed wersją 11, inicjalizacja tablicy listą parametrów:
int numbers[] = {1, 2, 3, 4, 5}; // tablica w stylu C
była OK, ale inicjalizacja, dajmy na to, wektora:
vector<int> numbers = {1, 2, 3, 4, 5}; // klasa vector
powodowała błąd kompilacji.
C++11 wprowadza tzw. listy inicjalizatora, dzięki którym możemy inicjalizować obiekty od razu całą listą parametrów. Taka inicjalizacja możliwa jest out-of-the-box np. dla wszystkich klas kontenerowych STL. Wygodne :)
Wykorzystanie we własnej klasie
Listy inicjalizatora możemy wykorzystać również we własnych klasach.
Żeby stworzyć koszyk, do którego będzie można łatwo wrzucić itemy, np. tak:
Basket basket = {"jabłko", "śliwka", "pomarańcza"};
, trzeba klasie Basket zapewnić konstruktor z listą inicjalizatora:
#include <initializer_list> #include <string> #include <vector> #include <iostream> using namespace std; class Basket { private: vector<string> items; public: Basket(const initializer_list<string>& li) : items(li) { printItems(); } void printItems() { for (string s : items) cout << s << endl; cout << endl; } };
Konstruktor przyjmujący parametr const initializer_list<string>& li pozwala nam inicjalizować nowe obiekty typu Basket całymi grupami elementów. Wykonujemy:
Basket basket = {"jabłko", "śliwka", "pomarańcza"};
, i dostajemy:
jabłko sliwka pomarańcza
Działa to dokładnie tak samo, jak dla klasy vector, set czy map.
Zmienne listy prametrów
Lista inicjalizatora ułatwia jeszcze jedną rzecz – tworzenie funkcji, do których można przekazać dowolną liczbę parametrów jest dużo prostsze, niż w przypadku konstrukcji wykorzystującej va_args. Żeby do naszego koszyka można było dodawać wygodnie kolejne elementy, np. tak:
basket.addItems({"banan", "marchew"});
, trzeba naszą klasę Basket wyposażyć w metodę addItems przyjmującą jako parametr listę inicjalizatora:
#include <initializer_list> #include <string> #include <vector> #include <iostream> using namespace std; class Basket { private: vector items; public: Basket(const initializer_list<string>& li) : items(li) { printItems(); } void addItems(const initializer_list<string>& li) { items.insert(items.end(), li.begin(), li.end()); printItems(); } void printItems() { for (string s : items) cout << s << endl; cout << endl; } };
Jak widzisz, w pięciu linijkach kodu uzyskaliśmy poręczną metodę wrzucania do koszyka całych grup nowych elementów. Wykonujemy:
Basket basket = {"jabłko", "śliwka", "pomarańcza"}; basket.addItems({"banan", "marchew"});
, i dostajemy:
jabłko sliwka pomarańcza banan marchew
Łatwo, szybko i wygodnie. List inicjalizatora po prostu nie da się nie lubić ;)