C++ cast Operatoren
-
unskilled schrieb:
ein C-cast ist ein dynamic_cast und static_cast und const_cast in einem
dynamic_castist wirklich neu, C kennt nicht einmal Vererbung.
Da sich die "C++ casts" in der Benutzung wie Template-Funktionen anfühlen, kann man sich leicht eigene Casts bauen, die optisch den spracheigenen ähneln. Ein bekanntes Beispiel dafür istboost::dynamic_pointer_cast, der einendynamic_castspeziell für Smart Pointer darstellt.Man könnte auch solchen Blödsinn damit machen:
template <class T> std::list<T> list_cast(const std::vector<T> &);Hilfreich kann ein eigener Cast bei folgendem Beispiel sein:
template <class T> struct vector2d { T x, y; //... }; template <class T, class U> vector2d<T> vector_cast(const vector2d<U> &v) { return vector2d<T>(static_cast<T>(v.x), static_cast<T>(v.y)); } int main() { vector2d<float> calculatedPoint = ...; DrawPixel(vector_cast<int>(calculatedPoint), ...); }
-
TyRoXx schrieb:
Man könnte auch solchen Blödsinn damit machen:
template <class T> std::list<T> list_cast(const std::vector<T> &);Wenn du die Funktionen jetzt statt xxx_cast noch make_xxx nennst, also make_list oder make_vector, oder von mir aus to_vector oder to_list, dann würde ich das nichtmal mehr blödsinnig nennen

-
Also wenn die IDE regex-Suche hat, sollte man die C-Casts problemlos finden. Da ist die Schreibweise kein Argument.
Und das hier ist doch wohl ein Konstruktor-Aufruf und kein cast:
double(3);
-
Stefan schrieb:
Also wenn die IDE regex-Suche hat, sollte man die C-Casts problemlos finden. Da ist die Schreibweise kein Argument.
Klar, wenn man direkt nach Casts sucht, wunderbar. Wenn man aber einen Fehler (durch einen Cast) hat, bei dem man die Ursache nicht so genau kennt, ist es schwierig danach zu suchen.
-
@__Stefan__:
double hat aber keinen Konstruktor.Die Notation T(x) ist im Standard explizit als äquivalent zum Cast-Ausdruck (T)x definiert. Dass da manchmal ein Konstruktor aufgerufen wird, ist klar, weil man nur so Objekte von Klassentypen erzeugen kann. Das macht aus dem ganzen aber noch keinen "Konstruktoraufruf".
-
Stefan schrieb:
Und das hier ist doch wohl ein Konstruktor-Aufruf und kein cast:
double(3);Dann ist
static_cast<std::string>("")auch kein Cast.
-
Hast du das denn wirklich mal gebraucht?
Für mich hört sich dieses Wiederfindbarkeits-Feature irgendwie konstruiert an.
Ich hab's zumindest niemals nutzen müssen und daran wird sich auch ziemlich sicher nichts ändern.
-
Jockelx schrieb:
Hast du das denn wirklich mal gebraucht?
Für mich hört sich dieses Wiederfindbarkeits-Feature irgendwie konstruiert an.
Ich hab's zumindest niemals nutzen müssen und daran wird sich auch ziemlich sicher nichts ändern.Es geht eher darum, dass man den Cast leichter erkennt. Ein
static_castgeht nicht so leicht im Code unter wie irgendein Typname mit Klammern dahinter.
-
Jockelx schrieb:
Hast du das denn wirklich mal gebraucht?
Für mich hört sich dieses Wiederfindbarkeits-Feature irgendwie konstruiert an.
Ich hab's zumindest niemals nutzen müssen und daran wird sich auch ziemlich sicher nichts ändern.Es geht nicht nur um Wiederfindbarkeit. Zum Einen sind die C++-Casts sicherer, weil es keine impliziten Reinterpretierungen gibt. Wenn man versucht, mit static_cast etwas zu reinterpretieren, gibt es einen Fehler.
Zum anderen erhöht es die Konsistenz. Um dynamic_cast kommt man nicht herum. Wenn man die C++-Syntax konsequent benutzt, ist es im Code durchgängig, und man keinen Mix von unterschiedlichen Casts.
Das es auch Bibliotheks-Template-Casts gibt, wurde ja bereits erwähnt. Auch hiermit bleibt man konsistent, wenn man C++-Casts benutzt.
-
Tachyon schrieb:
Es geht nicht nur um Wiederfindbarkeit.
Doch, offenbar schon. Ich hab nicht die C++-Casts hinterfragt, sondern dieses komische Wiederfind-Argument.
-
Stefan schrieb:
Also wenn die IDE regex-Suche hat, sollte man die C-Casts problemlos finden. Da ist die Schreibweise kein Argument.
Dann poste doch bitte mal ne Regex mit der man alle C-Style Casts finden kann. Natürlich ohne massiv viele false-positives zu bekommen. Ich wäre dir sehr dankbar dafür. Wäre ein nützliches Werkzeug beim Refactoring von altem Code.
Ich kenne auf jeden Fall keine solche Regex. Ich wüsste auch nicht wie man eine schreiben sollte.Und das hier ist doch wohl ein Konstruktor-Aufruf und kein cast:
double(3);Nope, das ist ein Cast. Lies es im Standard nach wenn du es nicht glaubst.
Damit kann man auch ganz böse Dinge machen:
typedef int* pint; char const* str = "lala"; int* i = pint(str); // castet const weg + char* nach int*Gerade weil er so harmlos aussieht, wie ein ganz unschuldiger ctor Aufruf eben, finde ich den "function style" Cast auch so schlimm.
-
Jockelx schrieb:
Hast du das denn wirklich mal gebraucht?
Für mich hört sich dieses Wiederfindbarkeits-Feature irgendwie konstruiert an.
Ich hab's zumindest niemals nutzen müssen und daran wird sich auch ziemlich sicher nichts ändern.Ich hatte schon öfters Fälle, in denen ich gerne nach Casts gesucht hätte.
Speziell reinterpret_cast und const_cast.Nach C-Style Casts und Function-Style Casts würde ich deswegen gerne suchen können, damit ich sie als xxx_cast umschreiben kann. Damit sichtbarer ist was passiert, und damit ich in weiterer Folge dann nach den potentiell problematischen Casts wie eben reinterpret_cast und const_cast suchen kann.
Und zur Frage warum man nach Casts suchen wollen würde: z.B. einfach um beim Bug-Hunting gewisse Dinge vorab kontrollieren und idealerweise ausschliessen zu können.
-
-
Hast du etwa nie Funktionen mit nur einem Parameter?
BTW: Kennt CodeBlocks keine Gruppierungen oder warum musst du die Klammern nicht escapen?
-
Michael E. schrieb:
Hast du etwa nie Funktionen mit nur einem Parameter?
BTW: Kennt CodeBlocks keine Gruppierungen oder warum musst du die Klammern nicht escapen?
Sobald du noch den Parameternamen mit einem space hast, ignoriert er es ja. Den Regex typ kann man in Codeblocks umstellen.
-
Jockelx schrieb:
Für mich hört sich dieses Wiederfindbarkeits-Feature irgendwie konstruiert an.
Ich hab's zumindest niemals nutzen müssen und daran wird sich auch ziemlich sicher nichts ändern.Geht mir genauso.
-
Stefan schrieb:
Sobald du noch den Parameternamen mit einem space hast, ignoriert er es ja.
Also müsste ich jedes Mal in einer Argumentliste noch ein Leerzeichen schreiben? Ich glaube, das machen die Wenigsten.
-
Stefan schrieb:
In codeblocks geht's so:
(\w+).+Ich gebe zu, es ist nicht 100% zuverlässig

Ja, sowas kann ich mir auch selbst basteln.
foo((TypeA::TypeB) x); // cast bar((std::min)(a, b)) // kein cast, nur seltsame schreibweise um verwechslung mit dem #define min zu verhindern baz((typename X<T>::Y)(123 * 234)) // cast // ...
-
Stefan schrieb:
Ich gebe zu, es ist nicht 100% zuverlässig

Es geht nicht nur ums Suchen. Wenn ich im Quellcode stöbere und const_cast sehe, werde ich erst mal aufmerksam und erkenne, dass hier eine potenzielle Gefahrenquelle lauert und denke vielleicht sogar über Alternativen nach. Wenn hingegen ein C-cast vorkommt, dessen primäre Aufgabe eigentlich nicht im const-wegcasten besteht, ist das schon viel mühsamer, besonders bei der Bugsuche.
-
Finder (nicht Sucher) schrieb:
Stefan schrieb:
Ich gebe zu, es ist nicht 100% zuverlässig

Es geht nicht nur ums Suchen. Wenn ich im Quellcode stöbere und const_cast sehe, werde ich erst mal aufmerksam und erkenne, dass hier eine potenzielle Gefahrenquelle lauert und denke vielleicht sogar über Alternativen nach. Wenn hingegen ein C-cast vorkommt, dessen primäre Aufgabe eigentlich nicht im const-wegcasten besteht, ist das schon viel mühsamer, besonders bei der Bugsuche.
Es ist alles gesagt worden. Wer die Vorteile erkennt, nimmt eben die längere Schreibweise und wer an C hängt, macht es eben weiterhin so.