2013-08-18 3 views
9

Ich habe gerade zwei Fragen über Array und Wert Initialisierung here und gestellt. Aber mit diesem Code, ich bin verloren:Warum std :: array <int, 10> x ist nicht gleich Null initialisiert aber std :: array <int, 10> x = std :: array <int, 10>() zu sein scheint?

#include <iostream> 
#include <iomanip> 
#include <array> 

template <class T, class U = decltype(std::declval<T>().at(0))> 
inline U f1(const unsigned int i) 
{T x; return x.at(i);} 

template <class T, class U = decltype(std::declval<T>().at(0))> 
inline U f2(const unsigned int i) 
{T x = T(); return x.at(i);} 

int main() 
{ 
    static const unsigned int n = 10; 
    static const unsigned int w = 20; 
    for (unsigned int i = 0; i < n; ++i) { 
     std::cout<<std::setw(w)<<i; 
     std::cout<<std::setw(w)<<f1<std::array<int, n>>(i); 
     std::cout<<std::setw(w)<<f2<std::array<int, n>>(i); 
     std::cout<<std::setw(w)<<std::endl; 
    } 
    return 0; 
} 

Wie erwartet, f1 beliebige Werte zurück, wie seine Werte nicht Null initialisiert sind. Aber f2 scheint ausschließlich Nullwerte zurück:

    0     0     0 
        1     61     0 
        2     0     0 
        3     0     0 
        4   297887440     0 
        5    32767     0 
        6    4196848     0 
        7     0     0 
        8   297887664     0 
        9    32767     0 

Ich persönlich dachte, dass f2 wird ein Array mit beliebigen Werten erstellen und kopieren/verschieben Sie es in x. Aber es scheint nicht der Fall zu sein.

Also, ich habe zwei Fragen:

  • Warum?
  • Do C++ 11 std::array<T, N> und C-Stil T[N] haben das gleiche Verhalten in einer solchen Situation?
+3

'T()' ist ein Wert-initialisiertes 'T'. Und ungültige Syntax, wenn "T" ein C-artiger Array-Typ ist. 'T x = {};' oder 'T x {};' sind allgemein anwendbare Syntaxen. – Casey

+0

@Casey-Wert Initialisierung gilt für C-artige Arrays. "T()" ist ein Syntaxfehler, wenn "T" kein Simple-Type-Specifier ist, d. H. Ein einzelner Bezeichner oder ein Schlüsselwort, das einen Typ bezeichnet. In C++ 03 gilt '= {}' nur für Arrays und das einfache '{}' ist ein Fehler. – Potatoswatter

+0

Das angenommene Duplikat ist über Wert-Initialisierung, aber diese Frage ist über Standard-Initialisierung. Bitte öffnen Sie erneut und finden Sie ein richtiges Duplikat, oder antworten Sie einfach. – Potatoswatter

Antwort

9

Mit {} oder () als initializer, mit oder ohne =, ergibt Wert Initialisierung. Bei einem Typ mit einem implizit deklarierten Konstruktor implementiert die Wertinitialisierung eine Nullinitialisierung, die, wie der Name schon sagt, jedes primitive Element auf 0 setzt. Dies tritt auf, bevor der Konstruktor ausgeführt werden kann, aber in diesem Fall führt der Konstruktor nichts aus.

Da der Konstruktor nichts tut (es ist trivial), ist es möglich, nicht initialisierte Daten zu sehen.

Wie für C-artige Arrays ist das Verhalten ähnlich, wenn Sie = {} anstelle von = T() verwenden, da letzteres illegal ist. T() würde nach einem temporären Array-Objekt fragen, das dem benannten Objekt zugewiesen werden soll, aber Arrays können nicht zugewiesen werden. = {} hingegen weist dem Array eine Klammer-Initialisierer-Liste zu, und eine Klammer-Initialisierer-Liste ist ein spezielles syntaktisches Konstrukt, das weder ein Ausdruck noch ein Objekt ist.

Verwandte Themen