Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » template auf Typen einschränken.

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 < [ 2 ]
000
03.02.2007, 22:20 Uhr
halber



Ich bin mir eigentlich schon ziemlich sicher das es nicht geht, aber vielleicht kann ich mich ja eines besseren belehren lassen.
Erstmal etwas Code zum besserem Verständnis meines Vorhabens.

C++:
class Schuh {
    // ...
};

template <typename T> class Schuhschrank {
    T *schuh;
    // ...
};


So das soll schon reichen. Ich hätte gerne, das ich die Typen für T auf Klassen beschränke, die entweder Schuh sind oder von Schuh erben. Ein int z.B. macht hier einfach keinen Sinn. Kann man sowas in C++ irgendwie bewerkstelligen?
Klar kann ich auch einfach einen Zeiger auf ein Schuh Objekt anlegen, aber dann könnte ich alle Schuh in den Schuhschrank stellen, die von Schuh erben. Ich will aber den Schuhschrank für einen speziellen Schuhtypen haben.
--
Ich bin faul und mein Computer ist schnell!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
03.02.2007, 22:36 Uhr
halber



Die einzigste Möglichkeit die ich sehe in etwa so etwas zu machen ist mit Makros. Das sähe dann etwa so aus.

C++:
#define SCHUHTYP(a)

class Schuh {
    // ...
};

class Turnschuh : public Schuh {
    // ...
};

class Schuhschrank {
    SCHUHTYP *schuh;
    // ...
};

int main( ) {
    // Erzeuge einen Schuhschrank für Turnschuhe
    SCHUHSCHRANK(Turnschuh)
    Schuhschrank schuhschrank_fuer_Turnschuhe;
}


Ich habe es jetzt nicht ausprobiert, aber ich denke man sieht was ich machen wollte. Diese Lösung finde ich allerdings alles andere als gut.
--
Ich bin faul und mein Computer ist schnell!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
03.02.2007, 22:47 Uhr
virtual
Sexiest Bit alive
(Operator)


Du musst Dich zunächst entscheiden, ob Du einen Fehler zur Laufzeit oder zur Kompile-Zeit haben willst:

Wenn er zur Laufzeit sein soll, genügt im Constructor von Schuhschrank ein einfach ein dynamiccast<Schuh*>(schuh). Wenn dies fehl schlägt mit einer bad_cast exception, wurde ein Falscher Typ verwendet.


Wenn es zur Kompilezeit sein soll, dann kenne ich nur folgenden dirty-Hack:

C++:
class Schuh {
};

class HalbSchuh : public Schuh {
};

class KeinSchuh {
};


template<typename T> class Schuhschrank {
        typedef int checker[(int)dynamic_cast<Schuh*>((T*)1)];
};


int main() {
//      Schuhschrank<KeinSchuh> a;
        Schuhschrank<Schuh> b;
        Schuhschrank<HalbSchuh> c;

        Schuh s;

}


Ich bin mir augenblicklich nicht sicher, ob das wirklich Portabel ist. Vermutlich nicht. Aber in diese Richtung kannst Du ja mal forschen.

Das dumme ist, daß der Kompiler eine unschöne Fehlermeldung wirft. Dh normalerweise solltest Du noch in der Zeile einen fetten Kommentar sdchreiben, warum denn hier ein Kompiler meckern könnte.
--
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
003
03.02.2007, 23:07 Uhr
halber



Der dyamiccast würde es aber auch erlauben in den Schuhschrank Schuhe vom Typ Turnschuh und vom Typ HalbSchuh hinein zu stellen ohne das eine Exception geworfen wird. Den dirty-Hack könnte man noch ausbauen. Danke für die Antwort aber ich glaube ich überdenke besser mein Softwaredesign nochmal.
--
Ich bin faul und mein Computer ist schnell!

Dieser Post wurde am 03.02.2007 um 23:07 Uhr von halber editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.02.2007, 23:54 Uhr
halber



Ich glaube die beste Möglichkeit ist folgendes:

C++:
class Schuh {
};

template <typename T> class Schuhschrank {
private:
    T *schuh;
public:
    Schuhschrank( T *s ) {
        Schuh *testSchuh = dynamic_cast<Schuh *> (s);
        if(!testSchuh) {
            // Fehler s nicht vom Typ Schuh abgeleitet.
        }
        if(typeid(schuh) != typeid(T)) {
            // Fehler falscher Schuh.
        }
        schuh = s;
    }
};


Man bekommt jetzt zwar erst zur Laufzeit einen Fehler aber es sollte funktionieren.
--
Ich bin faul und mein Computer ist schnell!

Dieser Post wurde am 04.02.2007 um 00:02 Uhr von halber editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
04.02.2007, 00:07 Uhr
Bruder Leif
dances with systems
(Operator)


Moin!

Muss es unbedingt ein Template sein?


C++:
class Schuh {
};

class Schuhschrank {
private:
    Schuh *schuh;
public:
    Schuhschrank( Schuh *s ) {
        schuh = s;
    }
};





Bearbeitung von Leif:
OK, wenns nur für bestimmte abgeleitete Klassen gelten soll, bau Dir eine "Zwischenklasse" oder prüf den Typ beim Einfügen...

--
Mit 40 Fieber sitzt man nicht mehr vor dem PC.
Man liegt im Bett.
Mit dem Notebook.

Dieser Post wurde am 04.02.2007 um 00:09 Uhr von Bruder Leif editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
04.02.2007, 01:53 Uhr
0xdeadbeef
Gott
(Operator)


Wenn du eh nur einen ganz speziellen Typ erlauben willst, warum schreibst du dann überhaupt ne template?

Ansonsten hab ich in einer factory-template mal folgendes benutzt:

C++:
template<typename key_t,
         typename value_t
         typename compare_t = std::less<key_t> > class factory {
public:
  template<typename reg_t> void register_type(key_t const &key) {
    assert_valid_type(static_cast<reg_t const *const>(0));

    // ...
  }

private:
  inline static void assert_valid_type(value_t const *const) throw() { }
};


...auf die Art gibts auch lesbare Compilerfehler. Die Idee ist aber die selbe wie bei virtual.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
04.02.2007, 21:33 Uhr
halber




Zitat von 0xdeadbeef:
Wenn du eh nur einen ganz speziellen Typ erlauben willst, warum schreibst du dann überhaupt ne template?


Weil ich etwas 20 verschiedene Schuharten habe, und ich verhindern muss das zwei verschiedene Schuharten in einen Schuhschrank kommen könnten.

Der Sinn deines Codes bleibt mir im Moment verborgen. Außerdem habe ich keine Eigenschaft, die es erlaubt meine Schuhe zu Sortieren. Sprich ich habe keinen < Operator.
--
Ich bin faul und mein Computer ist schnell!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
07.02.2007, 10:16 Uhr
stephanw
localhorst



Zitat:
Weil ich etwas 20 verschiedene Schuharten habe, und ich verhindern muss das zwei verschiedene Schuharten in einen Schuhschrank kommen könnten.


Zwei Fragen dazu:

1.) Wie werden die verschiedenen Schuharten im Programm repräsentiert ? Durch 20 verschiedene Ableitungen der Klasse "Schuh" ? Oder durch eine beliebige Hierarchie mit "Schuh" als Basis ? Oder schlicht als Eigenschaften der Objekte von Schuh ?

2.) Warum ist es für den Schuhschrank so wichtig, dass nur genau eine Sorte Schuhe darin vorkommen darf ? Ist es wirklich für den Schuhschrank wichtig oder für das Programm insgesamt, den Benutzer oder sonstige Beteiligte ?

Davon würde ich es abhängig machen, wie die konkrete Lösung dann aussieht.
--
Reden ist Schweigen und Silber ist Gold.

Dieser Post wurde am 07.02.2007 um 10:17 Uhr von stephanw editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
07.02.2007, 12:25 Uhr
halber



Zur Frage 1:
Die Schuharten werden durch verschiedene Ableitungen der Klasse Schuh repräsentiert. Also 20 mal
C++:
class IrgendwasSchuh : public Schuh {
};

bzw.
C++:
class IrgendEinAndererSchuh : public IrgendwasSchuh {
};

usw.

Zur Frage 2:
Der Schuhschrank sollte nur eine Art an Schuhen beinhalten, da ich mir eine sehr aufwendige Funktion so ersparen kann, die die Schuhe zu Gruppen ihrer Art zusammenfasst. Da ich hier auch von etwa 20000 Schuhen rede ist die Laufzeit da nicht mehr die beste. Deshalb wollte ich verschiedene Schuhschränke. Aber ich habe das Problem jetzt durch eine ziemlich lange if else Kette gelöst. Ist nur dumm wenn wieder eine neue Schuhart dazu kommt. Dann darf ich die if else Kette nämlich jedesmal abändern.
--
Ich bin faul und mein Computer ist schnell!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ 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: