Bei einem Array a
möchte countof(a)
die Anzahl der Elemente im Array als Kompilierzeitkonstante liefern. Wenn ich einen Zeiger p
habe, möchte ich countof(p)
nicht kompilieren. Dies scheint so zu sein, als ob es (1) einfach und (2) häufig in SO enthalten sein sollte, aber (1) ich kann es nicht zum Laufen bringen, und (2) Suche nach SO ergab nichts.
Hier ist mein Versuch.
%Vor%Hilfe?
besteht beide Tests. Es gibt keine Möglichkeit, ein int*
in ein T const(&)[N]
zu konvertieren, daher ist kein Code zum Deaktivieren erforderlich.
Um es zu erweitern, sollten wir hinzufügen:
%Vor% Ich könnte sogar versucht sein, es auf den Aufruf von size()
für Container zu erweitern. Während es normalerweise keine Kompilierzeit sein wird, könnte die Einheitlichkeit nützlich sein:
oder was hast du.
%Vor% Das ist ziemlich ausführlich, gibt uns aber std::array
support, std::initializer_list
support, C-style array support - alles zur Kompilierzeit - und zur Laufzeit sind Standardcontainer und Strings alle countof
cable. Wenn Sie einen Zeiger übergeben, wird Ihnen mitgeteilt, dass die von Ihnen aufgerufene Funktion delete
ed ist.
Ich habe versucht, in diesem Fall eine static_assert
zu erstellen, aber es kam zu Problemen mit der Auflösungsregel, dass jede template
eine gültige Spezialisierung haben muss. Ich vermute, das Routing des gesamten Problems in eine Klasse countof_impl
mit SFINAE-basierten Spezialisierungen könnte dieses Problem beheben.
Ein Nachteil der Lösung =delete
oder static_assert
ist, dass es tatsächlich eine Überladung für Zeiger gibt. Wenn Sie das nicht haben, dann gibt es einfach keine gültige Funktion zum Aufrufen, die einen Zeiger benötigt: das ist näher an der Wahrheit.
Wenn Sie alle Dimensionen abflachen müssen, kann dieser Auszug in der Hand sein
%Vor%Verwenden Sie ein Beispiel:
%Vor% Für diejenigen unter uns, die Legacy-C ++ - Compiler ohne C ++ 11 constexpr
verwenden müssen, funktioniert Folgendes:
Diese Technik stellt die Kompilierzeitauswertung von countof
sicher, indem die ADL in den Operator sizeof
eingebettet wird.