Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Argumentüberprüfung bei Template-Funktionen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
21.10.2005, 12:13 Uhr
xenayoo



Wie man erkennt, bin ich C++-Anfänger. Ich habe mich durch Arnold Willemers Buch "C++ für Einsteiger" durchgebissen und nun kaue ich an Bjarne Stroustrups 'Bibel' "Die C++ Programmiersprache".
Mir ist so einigermassen klar, wofür Templates eingesetzt werden - nämlich einen allgemein gültigen Algorithmus für alle Type zu schreiben, ohne dies für jeden Typ erneut tun zu müssen. Jedoch ist ein Algorythmus nicht immer für jeden Typ sinnvoll. Gibt es eine Möglichkeit in einer Template-Funktion auf den Parametertyp zu prüfen und einen Fehlercode zu erzeugen, falls der Typ unpassend ist.

z.B. eine Template-Funktion, die wie abs() nur positiver Werte zurückgibt. Falls jedoch bool- oder char-Typen als Argument übergeben werden, soll die Funktion doch einen negativen Wert - etwa -1 -liefern.

Wie geht das? Und bitte auf 'deutsch für Dummies'....
--
Wer Rechtschreibfehler findet, darf sie behalten.... ;)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
21.10.2005, 12:56 Uhr
virtual
Sexiest Bit alive
(Operator)


Du hast generell zwei Möglichkeiten, sowas zu machen. Die eine ist die (partielle) Templatespezialisierung. Bezogen auf Dein Beispiel mit abs könnte man also ein allg. abs template bauen:

C++:
template<typename T>
T abs(const T& a) {
    return a>=0? a:-a;
}


Und dann schreiben:

C++:
template<>
bool abs<bool>(const bool& a) {
    throw std::runtime_exception("FALSCH: BOOLS HABEN KEIN ABS!");
}


(Da bei abs der Rückgabewert naturgemäß den gleichen Typen hat wie der Parameter, kann ich keine -1 zurückgeben, ich werfe also eine Exception.
Denkbar ist auch, gültige, performantere Spezialiserungen zu schreiben. Etwa für ein unsigned ist abs eigentlich ja ein NOP:

C++:
template<>
unsigned abs<unsigned>(const unsigned& a) {
    return a; // Kein vergleich notwendig, ist immer >= 0!
}




Ein solcher Fehler komtm halt erst zu Ausführungszeit hoch. Manchmal ist man auch daran interessiert, einen Fehler zur Compiletime zu haben. Das wird dann tricky und dirty:

C++:
template<typename T>
class irgendwas {
    typedef char dummy[sizeof(int)-sizeof(T)]; // WENN DER COMPILER HIER ABBRICHT, IST T ZU KLEIN!
};


Versucht man dieses Template für einen Typen zu instantiieren, welcher hinsichtlich Speicherplatz kleiner als ein int ist, geht das nicht, weil der Compiler spuckt. Dies ist insofern schmutzig, weil der Compiler eine mehr oder weniger nichtssagende Meldung ausgibt und man erst im Source (welcher hoffentlich dokumentiert ist!) nachschauen muß, was schiefgegangen ist. Vorteile: Kostet 0 Byte im Binary und wird bereits zur Compilezeit erkannt.

EDIT: KLeine Korrektur bei abs<unsigned>
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 21.10.2005 um 13:43 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
21.10.2005, 13:36 Uhr
xenayoo



Absolute Spitze!!!! Selten bekommt man in Foren derart verständliche Antworten. Vielen Dank.

Da hab ich aber noch viel zu lernen, bis ich solche Kniffe drauf hab.....

Bis zu meiner nächsten Frage..
--
Wer Rechtschreibfehler findet, darf sie behalten.... ;)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
21.10.2005, 13:44 Uhr
virtual
Sexiest Bit alive
(Operator)


Danke für Die Blumen
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
21.10.2005, 13:53 Uhr
xenayoo



Kurze Frage noch:

Dein letzer dirty Tricky ist in einer Template-Klassen-Definition untergebracht. Wenn ich das Ganze 1:1 in einer Template-Funktion unterbringe, was passiert dann? Eine Funktion wird ja nicht "instanziert". Etwa so:

C++:
...
template <class T>
T Betrag(T a)
{
    typedef char dummy [sizeof(int)-sizeof(T)];
    return (a > 0) ? a : -a;
}


Fragen über Fragen.....
--
Wer Rechtschreibfehler findet, darf sie behalten.... ;)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
21.10.2005, 14:13 Uhr
virtual
Sexiest Bit alive
(Operator)


Ja, du kannst Das auch in normalen Funktionstemplates machen, weil Du in Funktionen generell lokale Typedefs einführen darfst.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
21.10.2005, 14:16 Uhr
xenayoo




--
Wer Rechtschreibfehler findet, darf sie behalten.... ;)

Dieser Post wurde am 21.10.2005 um 14:19 Uhr von xenayoo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
21.10.2005, 14:23 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat von xenayoo:
Kurze Frage noch:

Dein letzer dirty Tricky ist in einer Template-Klassen-Definition untergebracht. Wenn ich das Ganze 1:1 in einer Template-Funktion unterbringe, was passiert dann? Eine Funktion wird ja nicht "instanziert".

Was mr noch einfällt:
Der Begriff "Instantiierung" ist in gewisser weise doppelt belegt: Läßt man mal Template beiseite, so spricht man von Instantiierung, wenn zu einer vorhandenen Klasse ein Objekt angelegt wird.
Nimmt man Templates hinzu, gehen manche Leute hin und bezeichnen die Konkretisierung eines Templates hin zu einem Typen ebenfalls als "instantiierung". Zu verdeutlichung:

C++:
template <typename T>
T abs(const T& a) {
   return a>0?a:-a;
}


Ist zunächstmal nur ein Template, also eine Vorlage. Ein Kompiler kann unmöglich wissen, was dem Benutzer so alles für "T" einfallen mag. Daher kann der Kompiler für dieses Template auch erstmal garkeinen Code generieren. Erst, wenn Du konkret sagst:

C++:
int i = -4711;
int j = abs(i);


Dann weiß der Kompiler: "oh, in der zweiten Zeile wird ja abs verwendet, und zwar für ein T = int." Daraufhin - das kann man sich vereoinfachend so vorstellen - geht der Compiler hin, nimmt das Template und ersetzt alle Ts durch "int" und compiliert diese Funktion. (Gleiches Gilt mit Klasse). Denn erst jetzt weiß der Compiler konkret (daher Konkretisierung), was das T eigentlich ist.

Genau bei dieser Konkretisierung würde der Compiler über solche Hacks wie im Post zuvor stolpern: In meinem Beispiel würde es sageb: "Hopsa, ein Array negativer Größe (denn das macht das Typedef ja) kann ich nicht darstellen."

Mir scheint, du meinst mit Instantiierung das erstgenannte; dies spielt hier jedoch keine Rolle.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
24.10.2005, 13:35 Uhr
RHBaum



Aehm wie ist das im Standard eigentlich geregelt, mit "Konkretisierung" und "Instanziierung".

Ich meine zumindest beim MS Compiler ist die Konkretisierung an die Instanzierung/Benutzung gebunden, also Ich muss ein Object instanzieren/benutzen, um ein konkretes Template zu kompilieren .... Membermethoden werden auch erst kompiliert, wenn sie wirklich benutzt werden. Um fehler zu finden, muss ich halt die entsprechende methode auch irgendwo mal aufrufen ....

also sprich bei :
typdef MyTemplate<MyClass> MyTemplateClass;
oder
MyTemplate<MyClass>& mrxClass;

wird das template in der auspraegung nicht compiliert, sondern nur die symbole erstellt, erst bei Instanzierung, bzw das aufrufen eines members wird der dazugehoerige code compiliert ...
Ist das generell so oder compilerspezifisch ?

Ciao ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
24.10.2005, 15:57 Uhr
virtual
Sexiest Bit alive
(Operator)


Also ich weiß nicht, wie die Nomenklatur im Standard genau ist, ob da "Konkretisierung" vorkommt (habe den Standard grade nicht da). Aber im Prinzip kenne ich zumindest keinen Compiler der es anders handhaben würde, wie du beschrieben hast
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: