Advanced Java Services | sdt::array C++11 |
Eine vollständige Dokumentation des Templates array findet man auf den beiden Referenzseiten
http://www.cplusplus.com/reference/array/array/ http://en.cppreference.com/w/cpp/container/array
Das Template template<class T, size_t N>class array kapselt ein Array des Typs T. Durch Einsetzen eines konkreten Typs wird das Template zu einer Klassse.
Zitat aus cplusplus.com :
Arrays are fixed-size sequence containers: they hold a specific number of elements ordered in a strict linear sequence.
Internally, an array does not keep any data other than the elements it contains (not even its size, which is a template parameter,
fixed on compile time). It is as efficient in terms of storage size as an ordinary array declared with the language's bracket
syntax ([]). This class merely adds a layer of member and global functions to it, so that arrays can be used as standard containers.
Unlike the other standard containers, arrays have a fixed size and do not manage the allocation of its elements through
an allocator: they are an aggregate type encapsulating a fixed-size array of elements. Therefore, they cannot be expanded or
contracted dynamically (see vector for a similar container that can be expanded).
Zero-sized arrays are valid, but they should not be dereferenced (members front, back, and data).
#include <array> using namespace std;
Die Syntax ist sehr einfach und kann ab C++11 für alle Containerklassen verwendet werden.
std::array<int, 5> intArr = { 1, 2, 3, 4, 5 };
Statt eines Literals kann auch eine Konstante verwendet werden, nicht aber eine Variable. In den geschweiften Klammern können weniger Elemente stehen, dann wird mit 0 initialisiert. Mehr Elemente führen zu einem Compilerfehler.
Ebenso einfach mit Hilfe von Initialisierungslisten
const int size = 4; // muß const sein !! std::array<string, size> stringArr = { "fee", "fi", "fo", "fum" };
Sind in der Liste weniger Element als size angibt, so werden diese Elemente mit dem Defaultkonstruktor initialisiert.
Vorsicht: Ebenso wie bei c-Arrays werden Arrays primitiver Datentypen nicht initialisiert. Es empfiehlt sich hier, die Methode fill zu verwenden, wie das folgende beispiel zeigt.
void initialize_fill_size_empty() { std::array<int, 0> emptyArr; cout << emptyArr.size() << endl; // 0 cout << emptyArr.empty() << endl; // 1 = true //cout << emptyArr[0] << endl; // runtimeerror cout << endl; std::array<int, 5> intArr; cout << intArr.size() << endl; // 5 cout << intArr.empty() << endl; // 0 = false // C++11 for-each for(int elem: intArr) cout << elem << " "; cout << endl; intArr.fill(17); // 5 mal die 17 for(int elem: intArr) cout << elem << " "; cout << endl; }
Die Methode macht die folgende Ausgabe.
0 1 5 0 4206368 2089943520 2293432 4203722 4203661 17 17 17 17 17
Hier ist die Situation im Grunde einfacher, da immer der Defaultkonstruktor aufgerufen wird. So werden im folgenden
std::array<string, 3> stringArr;
alle drei Element als leere Strings initialisiert.
Wie man der tabelle entnehmen kann existieren für std::array alle Iteratoren. Die folgende Funktion zeigt dies.
void std_array_iterators() { std::cout << "for mit iteratoren und auto\n"; std::array<int, 5> intArr = { 1, 2, 3, 4, 5 }; // länge wird gescheckt ! // zuwenig: dann wird mit 0 aufgefüllt // falls zuviel drinsteht: error: too many initializers for 'std::array<int, 5u>' // klassische for-schleife mit iteratoren std::cout << "intArr iterator\n"; for (std::array<int, 5>::iterator it = intArr.begin(); it != intArr.end(); it++) std::cout << (*it)++ << ' '; // ++ geht vor * std::cout << '\n'; std::cout << "intArr auto\n"; for (auto it = intArr.begin(); it != intArr.end(); ++it) std::cout << *it << ' '; std::cout << '\n'; std::cout << "intArr reverse_iterator\n"; for (std::array<int, 5>::reverse_iterator rit = intArr.rbegin(); rit != intArr.rend(); rit++) std::cout << (*rit)-- << ' '; std::cout << '\n'; std::cout << "intArr auto reverse\n"; for (auto rit = intArr.rbegin(); rit != intArr.rend(); ++rit) std::cout << *rit << ' '; std::cout << '\n'; std::cout << "intArr const_iterator\n"; for (std::array<int, 5>::const_iterator cit = intArr.cbegin(); cit != intArr.cend(); cit++) //std::cout << (*cit)++ << ' '; // increment of read-only location '* cit' std::cout << *cit << ' '; std::cout << '\n'; std::cout << "intArr const_reverse_iterator\n"; for (std::array<int, 5>::const_reverse_iterator crit = intArr.crbegin(); crit != intArr.crend(); crit++) //std::cout << (*cit)++ << ' '; // increment of read-only location '* cit' std::cout << *crit << ' '; std::cout << '\n'; }
Die Ausgabe ist offensichtlich.
for mit iteratoren und auto intArr iterator 1 2 3 4 5 intArr auto 2 3 4 5 6 intArr reverse_iterator 6 5 4 3 2 intArr auto reverse 5 4 3 2 1 intArr const_iterator 1 2 3 4 5 intArr const_reverse_iterator 5 4 3 2 1