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ć ;)

Related Posts: