enum-int casting: Operator oder Funktion

8

In dem externen Code, den ich verwende, ist enum:

%Vor%

In einem anderen externen Code, den ich verwende, gibt es 3 # define-Direktiven:

%Vor%

Oft habe ich int X, was gleich ValA oder ValB oder ValC ist, und ich muss es auf den entsprechenden Wert von En (ValA zu VALUE_A, ValB zu VALUEB usw.) umwandeln, weil eine Funktionssignatur enum En hat. Und oft muss ich die umgekehrte Operation machen, enum En in ValA oder ValB oder ValC übersetzen. Ich kann die Signaturen dieser Funktionen nicht ändern, und es gibt viele solche Funktionen.

Die Frage ist: Wie wird die Übersetzung gemacht? Soll ich 2 Cast-Operatoren erstellen, die implizit verwendet werden? Oder sollte ich nur 2 Übersetzungsfunktionen haben, die explizit verwendet werden:

%Vor%

Oder irgendeine andere Lösung?

    
Igor Oks 15.12.2008, 09:08
quelle

5 Antworten

11

Da Sie hier nicht einfach casten können, würde ich eine freie Funktion verwenden, und wenn es wahrscheinlich auch andere Enums gibt, die ebenfalls konvertiert werden müssen, versuchen Sie, es ein wenig wie die eingebauten Casts aussehen zu lassen:

%Vor%

Oder etwas Ähnliches - kann es anpassen, wenn Probleme bei der Verwendung auftreten.

Der Grund, warum ich keine implizite Konvertierung verwenden würde, ist, dass bereits eine implizite Umwandlung von En in int ist, was die falsche Antwort liefert. Selbst wenn Sie dies zuverlässig durch etwas ersetzen können, das die richtige Antwort liefert, sieht der resultierende Code nicht so aus, als ob er eine Konvertierung durchführt. IMO das wird jeden behindern, der sich später den Code mehr ansieht, als das Tippen eines Aufrufs zu einer Konvertierungsroutine wird Sie behindern.

Wenn Sie die Konvertierung in int und das Konvertieren von int sehr unterschiedlich gestalten möchten, können Sie der Vorlage und der Funktion verschiedene Namen geben.

Alternativ können Sie, wenn Sie möchten, dass sie gleich aussehen (und mehr wie eine statische_Sendung), Folgendes tun:

%Vor%

Wie geschrieben, muss T eine implizite Umwandlung von int haben. Wenn Sie T unterstützen möchten, das nur eine explizite Konvertierung hat, verwenden Sie "return T (ValA)". Stattdessen (oder "return static_cast & lt; T & gt; (ValA);", wenn man bedenkt, dass Konstruktoren mit einem einzigen Argument C-artige Umwandlungen sind und daher unzulässig sind).

    
Steve Jessop 15.12.2008, 11:14
quelle
2

Während implizites Casting bequemer ist als Übersetzungsfunktionen, ist es auch weniger offensichtlich, was passiert. Ein Ansatz, der sowohl praktisch als auch offensichtlich ist, könnte darin bestehen, eine eigene Klasse mit überladenen Cast-Operatoren zu verwenden. Wenn Sie einen benutzerdefinierten Typ in eine enum oder int umwandeln, wird es nicht einfach sein, ein benutzerdefiniertes Casting zu übersehen.

Wenn das Erstellen einer Klasse aus irgendwelchen Gründen keine Option ist, würde ich die Übersetzungsfunktionen verwenden, da die Lesbarkeit während der Wartung wichtiger ist als die Bequemlichkeit beim Schreiben des Codes.

    
foraidt 15.12.2008 09:22
quelle
1

Sie können Operatoren nicht für Enums überladen. Oder fehlt mir etwas? Nun, Sie könnten eine Art Dummy-Klasse erstellen, bei der ein impliziter Konstruktor ein int hat, und dann einen Umwandlungsoperator für eine enum (und umgekehrt).

Also, die einzige Lösung ist, Funktionen zu haben. Außerdem würde ich die Überladungen machen, wie Patrick es vorschlägt.

    
Paulius 15.12.2008 09:18
quelle
1

Funktionen haben und dann die Bibliotheksfunktionen überladen?

%Vor%     
Patrick 15.12.2008 09:15
quelle
-1

Konvertieren von enum-zu-int , z. int (VALUE_A), geschieht automatisch / transparent.

Konvertieren von int zu enum , z. En (ValA) , kann von der Überprüfung der Integrität profitieren, um sicherzustellen, dass der int Wert ein gültiges Mitglied der enum ist. ( Obwohl hoffentlich der Bibliothekscode nicht davon ausgeht, dass seine Werte enum überhaupt gültig sind.)

Es hilft zwar nicht bei " int x " -Fällen, aber Sie können etwas helfen, indem Sie Folgendes ändern:

%Vor%

An:

%Vor%

Vorausgesetzt enum En () ist überall enthalten / definiert, beide ValA und VALUE_A funktionieren für < strong> beide foo (int) und bar (En) überall automatisch / transparent.

Sie könnten verwenden:

%Vor%

Dabei ist STATIC_ASSERT etwa wie folgt:

%Vor%     
Mr.Ree 15.12.2008 10:31
quelle

Tags und Links