JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=ccead042b0fb931632d3209a038f3f6dMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Mini-Templates

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Tutorials
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Kampfhund
Super JLI'ler


Alter: 42
Anmeldedatum: 20.07.2002
Beiträge: 408

Medaillen: Keine

BeitragVerfasst am: 19.04.2006, 21:55    Titel: Mini-Templates Antworten mit Zitat

compiler_error:

Das ist eine ganz hilfreiche Technik um Fehler bereits zur Kompilierzeit aufzudecken.

Mal ein Beispiel(ist vielleicht nicht super gewählt):

CPP:
template<class T,int N>
struct static_array
{
   T array[N];
};


Jetzt kann es allerdings passieren, dass jemand für N 0 übergibt:

CPP:
static_array<int,0> array;


Das sollte natürlich nicht möglich sein. Um das zu verhindern kann man sich folgender Technik bedienen:

CPP:
template<bool generate_compiler_error>
struct compiler_error;

template<>
struct compiler_error<false>
{

};


Wie man sieht, gibt es zwei Spezialisierungen für compiler_error:
Eine für generate_compiler_error=true und eine für false. Die spezialisierung für true ist aber nicht definiert, denn der Struktur-Körper fehlt.

Wenn man also versucht, von compiler_error<true> eine Instanz anzulegen, dann meldet der compiler, dass die variable eine undefinierte Struktur verwendet. Dabei wird der Variablenname mit angegeben.

Das kann man nun so ausnutzen:

CPP:
template<class T,int N>
struct static_array
{
   compiler_error<N==0> zero_as_N_is_not_allowed;
   T array[N];
};


Wenn static_array nun mit 0 als N instantiiert wird, dann wird der Ausdruck "N==0" zur kompilierzeit zu "true" ausgewertet. Also wird compiler_error<true> instantiier, welche aber nicht definiert ist => compiler error.

Der Fehler sieht dan folgendermaßen aus:
Code:

'zero_as_N_is_not_allowed' uses undefined struct 'compiler_error<generate_compiler_error>


Man kann also sofort erkennen, dass man 0 nicht als N übergeben darf.

In boost ist diese Technik als "static assert" bekannt (afaik).


is_same_type:

Es soll nicht nur verboten sein, für N 0 zu verwenden, sondern auch T soll eine beschränkung haben: T != void.
Wie aber überprüft man, ob ein template-typ gleich einem bestimmten typ ist?

Dies erreicht man wieder durch partielle Spezialisierung. Wir schreiben uns ein template, dass ermittel, ob zwei typen gleich sind:

CPP:
template<class A,class B>
struct is_same_type
{
   enum { result = 0 };
}

template<class A> // spezialisierung für A=B
struct is_same_type<A,A>
{
   enum { result = 1 };
}


Wie man sieht, hat die template-struktur zwei template-parameter. Außerdem hat es einen anonymen (nicht benannten) Aufzählungstypen. Die template-struktur hat außerdem eine Spezialisierung, und zwar für den Fall dass A und B der selbe typ ist. Auch die Spezialisierung hat einen anonymen Aufzählungstypen.

Schauen wir uns an, was passiert, wenn die template-struktur verwendet wird:
CPP:
std::cout<<is_same_type<int,float>::result<<std::endl;


Hier wird nicht die Spezialisierung verwendet, also hat result (der wert aus der Aufzählung) den wert 0.

CPP:
std::cout<<is_same_type<int,int>::result<<std::endl;


Hier wird die Spezialisierung verwendet, demnach hat result den wert 1.

Man kann nun also durch diese struktur zur kompilierzeit feststellen, ob zwei typen die selben sind. Man muss dazu einfach nur is_same_type<A,B>::result als boolsche konstante ansehen die das ergebnis darstellt.

Wir können dies nun so verwenden:
CPP:
template<class T,int N>
struct static_array
{
   compiler_error<N==0> zero_as_N_is_not_allowed;
   compiler_error<is_same_type<T,void>::result> void_as_T_is_not_allowed; // neu
   T array[N];
};


Wenn T=void ist, dann wird die Spezialisierung von is_same_type instantiiert und result ist 1. Deswegen wird compiler_error<true> instantiiert, was - wie bereits gezeigt - eine compiler-fehlermeldung erzeugt.
_________________
Kochen ist ein NP-schweres Optimierungsproblem.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
GreveN
JLI Master


Alter: 38
Anmeldedatum: 08.01.2004
Beiträge: 901
Wohnort: Sachsen - Dresden
Medaillen: Keine

BeitragVerfasst am: 20.04.2006, 09:23    Titel: Antworten mit Zitat

So mag ich das, ist irgendwie... smart! Very Happy
Ist zwar anfürsich nichts Neues, aber klein, fein, nützlich... was will man mehr? Very Happy
Sehr schön!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Yahoo Messenger MSN Messenger
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Tutorials Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum