falscher ctor Aufruf... wie verhindern?
-
enum TestEnum { e1, e2 }; class Klasse { explicit Klasse( TestEnum e, int a) { } //ctor1 explicit Klasse( time_t t, int a = 0) { } //ctor2 }; int main() { TestEnum e = e1; Klasse k1( e, 1 ); //->korrekt ctor1 Klasse k1( e ); //->falsch ctor2 }Greift bei Enums die Typabfrage nicht oder wieso ruft er ctor2 auf (klar beides sind intern unsigned ints. Wie kann man einen derartigen Fehler vermeiden (OHNE die default Paramter bei ctor 2 zu entfernen)?
-
Häh? ctor1 passt doch schon von der Argumentenzahl nicht, wie soll das gehen? ctor2 ist eben der einzige Konstruktor der nur ein Argument hat. Und wieso machst du einen Konstruktor mit 2 Elementen explicit?
Kann's sein, dass du bei ctor1 ein Defaultargument möchtest und bei ctor2 nicht?
-
Der Compiler SOLL ja eine Fehlermeldung liefern. Tut es aber nicht weil er den time_t ctor verwendet.
Mit explicit wollt eich eben genau diese implizite Typumwandlung von TestEnum nach time_t vermeiden...Die "echte" Klasse ist eine Zeitklasse (die letztlich boost::date_time kappselt). Initilaisiere ich sie mit anderen Zeitobjekten benötige ich eben noch weitere Inforamtionen, wie zeitzone und ob die Zeit lokal oder utc ist.. Daher benötige ich weitere Parameter beim ctor.
-
muffmolch schrieb:
Mit explicit wollt eich eben genau diese implizite Typumwandlung von TestEnum nach time_t vermeiden...
Und dadurch, dass du den Konstruktor explizit aufgerufen hast, hast du die Typumwandlung ja auch erfolgreich erzwungen. Durch einen impliziten Konstruktoraufruf wäre das nicht gegangen. Genau dafür ist explicit da, wie der Name schon sagt
.edit: Wenn du Verhindern möchtest, dass time_t und TestEnum nicht ineinander konvertiert werden können, dann mach sie eben nicht konvertierbar. Wrap eine kleine Klasse drumherum. Aber sei vorsichtig, wenn du Konvertierungsoperatoren für diese Klassen schreiben möchtest :p .
-
ok, dann habe ich das immer missvertstanden. Ich ging davon aus, dass ein expliziter ctor NUR DANN verwendet wird, wenn alle Argumente vom entsprechenden Typ vorhanden sind. In meinem Fall ging ich davon aus, dass es einen Compilerfehler gibt, da time_t nunmal kein EnumTest ist. Aber wenn ich es richtig verstehe, so würde es hie rnur nicht klappen, wenn time_t (angenommen es sei eine echte Klasse) keinen expliziten ctor für mein Enum hätte und auch keine implizite Umwandlung ermöglichen würde. Richtig?
-
Stichwort scoped enumeration (C++11). Damit gibt es keine implizite Konvertierung in integer.
-
camper schrieb:
Stichwort scoped enumeration (C++11). Damit gibt es keine implizite Konvertierung in integer.
Ja, nur leider bin ich gezwungen mit VS2003 bzw VS2008 zu arbeiteten, da sieht es schlecht aus mit dem neuen Standard

-
Was ich in Deinem Fall machen würde, weiß ich nicht. Das kommt auch drauf an, was die Konstruktoren da semantisch machen.
Um die Überladungsauflösung bei Konstruktoren zu steuern habe ich auch mal Tag-Klassen verwendet.
struct dings_t{}; const dings_t dings = {}; struct bums_t{}; const bums_t bums = {}; class foo { public: foo(dings_t, int, int); // ctor 1 foo(bums_t, int, int); // ctor 2 }; : : int main() { foo f (dings,23,42); // ctor 1 foo g (bums,99,11); // ctor 2 }
-
Was du vermutlich brauchst, ist ein typsicheres enum, das sich nicht unter der Hand heimlich in irgendeinen integralen Typen verwandelt, der blöderweise hinter einem typedef das selbe wie ein time_t ist

schau mal hier: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Safe_Enum
-
@pumuckl:
Danke, das sollte mein Problem lösen!