type / non-type Unterscheidung
-
Hi,
kennt jemand einen Weg, um zur Compilezeit zwischen einem type / non-type Argument zu unterscheiden? So in etwa nach folgendem Prinzip:
irgendwas(int) // -> false int a; irgendwas(a) // -> true
Hatte eigentlich gehofft, dass man mit Makros und Templates was machen kann. Komm damit aber einfach nicht auf einen grünen Zweig...
-
moment
das ist doch vollkommender blödsinn, wozu soll den das gut sein ?
-
erklär mir, wie man typen als parameter übergeben kann, und ich erklär dir, wie mans erkennt
(mit andren worten: das ist absoluter schwachfug)
//edit wenns dir aber darum geht, zu erkennen, was ein übergebenere template typ ist, und das da oben im beispiel macros sind, dann kann ich versuchen, dir da was zu erklären
-
das ist doch vollkommender blödsinn, wozu soll den das gut sein ?
Nee, als Blödsinn würde ich das nicht bezeichnen. Schau dir nur mal sizeof an, das arbeitet genauso. Würdest du sizeof als blödsinnig bezeichnen? Mir ist aber schon klar, dass sizeof ein Schlüsselwort ist, was halt vom Compiler speziell unterstützt wird.
Genau genommen will ich mir damit etwas sizeof ähnliches basteln, ich hab es countof genannt. countof soll nicht die Gesamtgrösse eines built-in Arrays liefern, sondern die Anzahl der Elemente. Dafür hab ich eine Templateklasse erstellt, die dann ungefähr so zu handhaben ist:// fuer type typedef int a[10]; size_t n = meta::type<a>::size::array(); // fuer non-type int a[10]; size_t n = meta::type<>::size::array(a);
countof ist dann als Makro definiert, um damit wie mit einem Schlüsselwort zu arbeiten.
#define countof(x) meta::type<>::size::array(x)
Leider kann man so halt nur eine Art von Argument abdecken, type oder non-type, und nicht beide.
-
// 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ügungMein 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.