type / non-type Unterscheidung



  • // fuer type
    typedef int a[10];
    size_t n = meta::type<a>::size::array();
    

    ich bezweifle eigentlich, dass das Klappt, bei sowas sagt mir der gcc jedenfalls immer, dass er einen typ erwartet, aber a bekommt.

    // fuer non-type
    int a[10];
    size_t n = meta::type<>::size::array(a);
    

    das nimmt der gcc aufjedenfall nicht, da er soweit ich das sehen konnte, einen T[N] in T* umwandelt.



  • otze schrieb:

    ich bezweifle eigentlich, dass das Klappt, bei sowas sagt mir der gcc jedenfalls immer, dass er einen typ erwartet

    Welche GCC Version benutzt du denn? a ist jedenfalls ein Typ.

    otze schrieb:

    das nimmt der gcc aufjedenfall nicht, da er soweit ich das sehen konnte, einen T[N] in T* umwandelt.

    Das kommt darauf an, wie der Parameter von meta::type<>::size::array() definiert ist, und T* bzw. T[] ist das jedenfalls nicht.
    Mach dir mal keine Sorgen über die Implementierung, es funktioniert schon. Ich habs ja getestet, sowohl mit dem GCC als auch mit dem MSC. Wenn's dich interessiert, kann ich ja die Implementierung mal posten.
    Das ändert aber nichts an dem ursprünglichen Problem, wer deshalb trotzdem noch Vorschläge hat, nur her damit...



  • Wie wärs damit:

    #define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))
    


  • zum ersten: argh, typedef übersehen, ich werd aber auch immer schussliger
    zum zweiten: poste mal die implementation



  • 0xdeadbeef schrieb:

    Wie wärs damit:

    #define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))
    

    So sieht im Grunde meine alte Version aus. Das funktioniert aber halt nur mit non-type Argumenten.

    otze schrieb:

    zum zweiten: poste mal die implementation

    // type
    static size_t array()
    {
    	// T ist der Template Parameter der type Klasse
    	T tmp;
    	return sizeof(tmp) / sizeof(tmp[0]);
    }
    
    // non-type
    template <class T, size_t N>
    static size_t array(const T(&)[N])
    {
    	return N;
    }
    


  • (Sorry fürs Ausgraben eines Threads)

    In Modern C++ Design wird ja erwähnt, dass sizeof intern auch eine Art
    typeof Operator verwendet, somit schätz ich mal is es derzeit in Standard C++
    nicht möglich. Der g++ stellt halt freundlicherweise bereits den typeof
    Operator zur Verfügung, mit dem wär es möglich (zumindestens klappts bei mir).

    template<typename T>
    class array;
    
    template<typename T, size_t N>
    class array <T[N]> {
    	public:
    		static const size_t count = N;
    };
    
    #define countof(x) array<typeof(x)>::count
    
    void f()
    {
        int a[20];
    
        cout << countof(a) << '\n' // 20
             << countof(int [39]) << '\n'; // 39
    }
    

    Vielleicht hilfts 🙂



  • kleiner fehler am rande: ist der typ kein array gibts einen crash 😉

    template<typename T>
    class array;
    

    sollte so aussehen:

    template<typename T>
    class array{
        const static size_t count=0;
    };
    


  • kleiner fehler am rande: ist der typ kein array gibts einen crash

    Das war beabsichtigt.

    Man könnte natürlich ne Version von nem static assert verwenden
    mit einer Fehlermeldung, hielt ich aber für ein Beispiel nicht
    notwendig.



  • dann würde ich aber im zweifesfall ne nonstrict variante anbieten, die keinen fehler wirft. rückgabe ist ein fehlerwert, und damit kann dann weitergearbeitet werden.



  • Tankian schrieb:

    Der g++ stellt halt freundlicherweise bereits den typeof
    Operator zur Verfügung

    Mein Problem ist, dass es plattformunabhängig sein sollte. Mir reicht momentan allerdings, wenn's mit dem MSC und GCC funktioniert. Werd mir jedenfalls typeof mal anschauen und ein bissl damit rumspielen. Thx erstmal für den Tipp.


Anmelden zum Antworten