Advanced   Java   Services sdt::array  C++11


std::array

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 und Namespace
#include <array>
using namespace std;




Initialisierung mit Hilfe von Initialisierungslisten

Primitive Datentypen

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.


Klassen

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.


Initialisierung ohne Initialisierungslisten

Primitive Datentypen

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

Klassen

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.


Iteratoren

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