Kann jemand diesen Vorlagencode erklären, der mir die Größe eines Arrays gibt? [duplicate]

Lesezeit: 5 Minuten
template<typename T, size_t n>
size_t array_size(const T (&)[n])
{
    return n;
}

Der Teil, den ich nicht bekomme, sind die Parameter für diese Vorlagenfunktion. Was passiert mit dem Array, wenn ich es dort durchführe, das gibt n als die Anzahl der Elemente im Array?

Kann jemand diesen Vorlagencode erklaren der mir die Grose eines
Johannes Schaub – litb

Nun, zuerst müssen Sie verstehen, dass der Versuch, einen Wert aus einem Array zu bekommen, Ihnen einen Zeiger auf sein erstes Element geben kann:

int a[] = {1, 2, 3};
int *ap = a; // a pointer, size is lost
int (&ar)[3] = a; // a reference to the array, size is not lost

Referenzen beziehen sich auf Objekte unter Verwendung ihres genauen Typs oder ihres Basisklassentyps. Der Schlüssel ist, dass die Vorlage Arrays als Referenz verwendet. Arrays (keine Verweise darauf) als Parameter existieren in C++ nicht. Wenn Sie einem Parameter einen Array-Typ zuweisen, ist er stattdessen ein Zeiger. Daher ist die Verwendung einer Referenz erforderlich, wenn wir die Größe des übergebenen Arrays wissen möchten. Die Größe und der Elementtyp werden, wie allgemein bei Funktionsschablonen üblich, automatisch abgeleitet. Die folgende Vorlage

template<typename T, size_t n>
size_t array_size(const T (&)[n]) {
    return n;
}

Wird mit unserem zuvor definierten Array aufgerufen a wird implizit die folgende Funktion instanziieren:

size_t array_size(const int (&)[3]) {
    return 3;
}

Was so verwendet werden kann:

size_t size_of_a = array_size(a);

Es gibt eine Variation, die ich mir vor einiger Zeit ausgedacht habe [Edit: turns out someone already had that same idea here] die einen Wert zur Kompilierzeit bestimmen kann. Anstatt den Wert direkt zurückzugeben, gibt es der Vorlage einen Rückgabetyp abhängig von n:

template<typename T, size_t n>
char (& array_size(const T (&)[n]) )[n];

Sie sagen, wenn das Array hat n -Elemente ist der Rückgabetyp ein Verweis auf ein Array mit Größe n und Elementtyp char. Jetzt können Sie eine zur Kompilierzeit bestimmte Größe des übergebenen Arrays erhalten:

size_t size_of_a = sizeof(array_size(a));

Denn eine Reihe von char haben n Elemente hat sizeof n, das gibt Ihnen auch die Anzahl der Elemente im gegebenen Array. Zur Kompilierzeit, also können Sie das tun

int havingSameSize[sizeof(array_size(a))];

Da die Funktion nie wirklich aufgerufen wird, muss sie nicht definiert werden, also hat sie keinen Körper. Hoffe ich konnte die Sache ein wenig aufklären.

  • Danke litb Ich habe die gleiche Frage erst vor wenigen Minuten gepostet 🙂 Entschuldigung für die Vervielfältigung.

    – Khaled Alshaya

    24. Juli 2009 um 19:41 Uhr

  • freut mich, dass du Antworten gefunden hast. Keine Sorge wegen des Betrügers, du konntest es nicht wissen 🙂

    – Johannes Schaub – litb

    24. Juli 2009 um 19:42 Uhr

  • Nachteil der letzteren Variante, die einen geeigneten Rückgabetyp verwendet: Sie funktioniert nicht mit Microsoft Visual Studio 6 (das ziemlich schlecht mit Vorlagen umgehen kann und in diesem Fall fehlschlägt). Leider ein Deal-Breaker für einige Shops (wie der, bei dem ich arbeite, der MSVC6 unterstützen muss).

    – Frerich Raabe

    6. Mai 2011 um 6:02 Uhr

  • Mit C++11 constexpr, die ‘Rückgabe n;’ Funktion wird eine Kompilierzeitkonstante! template <typename T, size_t n> constexpr size_t array_size(const T (&)[n]) { return n; }

    – legends2k

    12. April 2012 um 13:22 Uhr


  • template char (& array_size(const T (&)[n]) )[n]; und Aufruf von sizeof(array_size(a)); Diese Gesamtgröße des Arrays zurückgeben = N * Größe des Zeichens, anstatt N – Anzahl der Elemente zurückzugeben?

    Benutzer6952310

    10. Oktober 2017 um 11:39 Uhr


Kann jemand diesen Vorlagencode erklaren der mir die Grose eines
Finsternis

Stellen Sie sich das so vor, nehmen Sie an, Sie hätten eine Reihe von Funktionen:

// Note that you don't need to name the array, since you don't
// actually reference the parameter at all.
size_t array_size(const int (&)[1])
{
    return 1;
}

size_t array_size(const int (&)[2])
{
    return 2;
}

size_t array_size(const int (&)[3])
{
    return 3;
}
// etc...

Wenn Sie das jetzt aufrufen, welche Funktion wird aufgerufen?

int a[2];
array_size(a);  

Wenn Sie nun die Arraygröße vorlagen, erhalten Sie:

template <int n>
size_t array_size(const int (&)[n])
{
    return n;
}

Der Compiler versucht, eine Version von array_size zu instanziieren, die mit jedem Parameter übereinstimmt, mit dem Sie es aufrufen. Wenn Sie es also mit einem Array von 10 Ints aufrufen, wird es array_size mit n = 10 instanziieren.

Erstellen Sie als Nächstes einfach eine Vorlage für den Typ, damit Sie ihn mit mehr als nur int-Arrays aufrufen können:

template <typename T, int n>
size_t array_size(const T (&)[n])
{
    return n;
}

Und du bist fertig.

Bearbeiten: Eine Anmerkung über die (&)

Die runden Klammern werden benötigt & um zwischen einem Array von int-Referenzen (illegal) und einem Verweis auf ein Array von ints (was Sie wollen) zu unterscheiden. Seit dem Vorrang von [] ist höher als &wenn Sie die Erklärung haben:

const int &a[1];

Aufgrund der Operatorpriorität erhalten Sie am Ende ein einelementiges Array von konstanten Verweisen auf int. Wenn du willst & zuerst angewendet, müssen Sie dies mit Klammern erzwingen:

const int (&a)[1];  

Jetzt haben Sie einen konstanten Verweis auf ein Array von Ints mit einem Element. In der Funktionsparameterliste müssen Sie den Namen eines Parameters nicht angeben, wenn Sie ihn nicht verwenden, also können Sie den Namen weglassen, aber die Klammern beibehalten:

size_t array_size(const int (&)[1])

  • Wie kommt es, dass Sie die Klammern um das & in der Vorlagenversion der Funktion benötigen, aber nicht in den obigen Beispielen, in denen die Array-Größe fest codiert ist?

    – Alex

    23. April 2009 um 19:40 Uhr

  • Sie brauchen die Klammern eigentlich in beiden Situationen.

    – Sonnenfinsternis

    23. April 2009 um 20:56 Uhr

Kann jemand diesen Vorlagencode erklaren der mir die Grose eines
MSN

Dem Array passiert nichts. Es ist ein nicht verwendeter Parameter, der verwendet wird, um die Signatur der Vorlagenfunktion aufzulösen.

Es kann auch nicht als Vorlagenargument verwendet werden, aber das ist eine separate Kleinigkeit.

Ein etwas seltsamer Weg, um das Ergebnis als Kompilierungszeitkonstante für diejenigen von uns zu erhalten, die “constexpr” nicht haben:

#include <iostream>

namespace
{

    template <size_t V>
    struct helper
    {
        enum
        {
            value = V
        };
    };


    template<typename T, size_t Size>
    auto get_size(T(&)[Size]) -> helper < Size >
    {
        return helper < Size >() ;
    }

    template<typename T>
    struct get_value
    {
        enum
        {
            value = T::value
        };
    };

}

int main()
{
    std::cout << get_value<decltype(get_size("Foo bar baz"))>::value;
}

989880cookie-checkKann jemand diesen Vorlagencode erklären, der mir die Größe eines Arrays gibt? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy