2010-06-23 10 views
6

Diese Syntax als Teil einer Antwort auf this question verwendet wurde:Bitte helfen Sie mir diese Syntax zu verstehen (implementierende statische assert in C++)

template <bool> 
struct static_assert; 

template <> 
struct static_assert<true> {}; // only true is defined 

#define STATIC_ASSERT(x) static_assert<(x)>() 

Ich verstehe nicht, dass die Syntax. Wie funktioniert es?

Angenommen ich

STATIC_ASSERT(true); 

es wird zu

umgewandelt
static_assert<true>(); 

Was nun?

+0

:) – GManNickG

Antwort

13
STATIC_ASSERT(true); 

bedeutet in der Tat

static_assert<true>(); 

, die zu nichts auswertet. static_assert<true> ist nur eine leere Struktur ohne Mitglieder. static_assert<true>() erstellt ein Objekt dieser Struktur und speichert es nicht überall.

Dies kompiliert einfach und tut nichts.

Auf der anderen Seite

STATIC_ASSERT(false); 

bedeutet

static_assert<false>(); 

die Übersetzungsfehler zur Folge hat. static_assert hat keine Spezialisierung für false. Daher wird eine allgemeine Form verwendet. Aber die allgemeine Form ist wie folgt gegeben:

template <bool> 
struct static_assert; 

das ist nur eine Deklaration einer Struktur und nicht ihre Definition. So verursacht static_assert<false>() Kompilierungsfehler, wie es versucht, ein Objekt einer Struktur zu erstellen, die nicht definiert ist.

+0

+1 Ausgezeichnete Erklärung – fingerprint211b

2

Nun, ich denke, es geht um Template-Spezialisierung. STATIC_ASSERT (true) wird erfolgreich kompiliert, da es eine Definition (nicht nur eine Deklaration) von "static_assert < true>" gibt.

STATIC_ASSERT (false) wird vom Compiler abgelehnt, da nur eine Deklaration für "static_assert < false>" und keine Definition existiert.

Update: für Visual Studio, static_assert (true) ist in Ordnung, aber static_assert (false) löst die Fehlermeldung: "Fehler C2514: 'static_assert < __formal>': Klasse hat keine Konstrukteure [mit __formal = false]"

9

static_assert<true>(); macht, dass

template <> 
struct static_assert<true> {} 

Templat-Struktur Spezialisierung temporäre Objekterstellung getan - Constructor einen Anruf und später zu einem destructor, die beide hoffentlich vom Optimierer beseitigt werden, da sie nichts zu tun. Da es nur eine Spezialisierung für true und keine generische Version der Template-Struktur gibt, werden alle Konstrukte, die zu static_assert<false>(); ausgewertet werden, nicht kompiliert.

+0

Danke für die Erklärung, ich fand mich selbst verloren in dieser Syntax. – PeterK

4

Im Ausdruck

static_assert<true>(); 

seit static_assert<true> ein Typ ist, wird es den Konstruktor von static_assert<true> nennen. Da static_assert<true> auf eine leere Struktur spezialisiert ist, wird nichts davon betroffen sein.


jedoch in

static_assert<false>(); 

da es keine Spezialisierung für static_assert<false>, die allgemeine Definition

template <bool> 
struct static_assert; 

verwendet wird. Aber hier ist der Typ static_assert<B>unvollständig. Der Aufruf des Konstruktors static_assert<B> führt daher zu einem Kompilierungsfehler.


Daher wird diese „static assert“ genannt, da die Anweisung wird die Kompilierung abbrechen, wenn der Ausdruck auf false, ähnlich die normal assert() function auswertet, die das Programm im laufenden Betrieb töten.

Verwandte Themen