Problem mit Bitoperatoren und enums
-
Nexus schrieb:
Dravere schrieb:
Ganz einfach:
AusSTYLE1 | STYLE2kommt einintheraus und nicht wie erwartet einenum. Daher muss man casten.Ja, das habe ich auch erwähnt. Aber da pumuckl die Funktion mit einem
int-Parameter deklariert hat...Achso, ich dachte du hättest von Don Quijote kopiert. Ganz übersehen, das asc das auch drin hatte. Ich denke mal er hat einfach ein Copy&Paste gemacht und vergessen, die Kommentare rauszunehmen. Programmiererfehler Nummer 1

Grüssli
-
Dravere schrieb:
Ich denke mal er hat einfach ein Copy&Paste gemacht und vergessen, die Kommentare rauszunehmen. Programmiererfehler Nummer 1

Man man man... Copy/Paste der Segen und Fluch der Programmierer.
-
asc schrieb:
Wenn du mit Flags arbeiten willst, solltest du
a) Beim Enum die Wertigkeit angeben
b) Einen Integralen Datentyp (int, long...) zur Übergabe verwenden// Enum-Definition enum Style { STYLE1 = 0x0001, // Bit 1 gesetzt STYLE2 = 0x0002, // Bit 2 gesetzt STYLE3 = 0x0004 // Bit 3 gesetzt }; void Func(int newStyle); // Nun klappen auch die aufrufe: // So geht's Func(STYLE2); // Das geht schief Func(STYLE1|STYLE2);cu André
Gut, das hat mir schonmal etwas weiter geholfen, aber was würde denn bei
Func(STYLE1|STYLE2)an die Funktion übergeben werden? beide Bits oder nur 0x0002?
-
Don Quijote schrieb:
Gut, das hat mir schonmal etwas weiter geholfen, aber was würde denn bei
Func(STYLE1|STYLE2)an die Funktion übergeben werden? beide Bits oder nur 0x0002?
Es käme ein 0x0003 an, oder in Bits ausgedrückt:
STYLE1 := 0000 0001 = 0x01 = 1 STYLE2 := 0000 0010 = 0x02 = 2 STYLE1 | STYLE2 := 0000 0011 = 0x03 = 3Grüssli
-
Ok vielen Dank euch allen für die schnelle Hilfe

-
void Func( int newStyle )womit aber die schoene typsicherheit der enums dahin waere...
Das kann nicht die beste Loesung sein
-
Geht aber nicht anders. Außer du definierst für jeden Müll einen Enumeintrag A_AND_B, B_AND_C, A_AND_B_AND_C etc.
-
Fellhuhn schrieb:
Geht aber nicht anders.
diesen Satz in Verbindung mit C++ zu lesen ist eine wahre Seltenheit...
Fuer alles Erdenkliche existieren Patterns, also warum nicht auch fuer sowas Elementares?
-
Du kannst natürlich das Ergebnis wieder zum Enum-Typ casten, dann geht es. Aber da du dann einen "ungültigen" Wert bekommen kannst, bringt dir der ganze Enum-Klumbatsch eh nichts mehr.
-
#include <iostream> enum A { AFlag1 = 1, AFlag2 = 2, AFlag3 = 4, AFlag4 = 8, }; enum B { BFlag1 = 1, BFlag2 = 2, BFlag3 = 4, BFlag4 = 8, }; template<typename Enum> class Flags { typedef void** Zero; int i; public: typedef Enum enum_type; Flags( const Flags& f ) : i( f.i ) {} Flags( Enum f ) : i( f ) {} Flags( Zero = 0 ) : i( 0 ) {} Flags& operator=( const Flags& f ) { i = f.i; return *this; } Flags& operator&=( int mask ) { i &= mask; return *this; } Flags& operator&=( uint mask ) { i &= mask; return *this; } Flags& operator|=( Flags f ) { i |= f.i; return *this; } Flags& operator|=( Enum f ) { i |= f; return *this; } Flags& operator^=( Flags f ) { i ^= f.i; return *this; } Flags& operator^=( Enum f ) { i ^= f; return *this; } operator int() const { return i; } Flags operator|( Flags f ) const { Flags g; g.i = i | f.i; return g; } Flags operator|( Enum f ) const { Flags g; g.i = i | f; return g; } Flags operator^( Flags f ) const { Flags g; g.i = i ^ f.i; return g; } Flags operator^( Enum f ) const { Flags g; g.i = i ^ f; return g; } Flags operator&( int mask ) const { Flags g; g.i = i & mask; return g; } Flags operator&( uint mask ) const { Flags g; g.i = i & mask; return g; } Flags operator&( Enum f ) const { Flags g; g.i = i & f; return g; } Flags operator~() const { Flags g; g.i = ~i; return g; } bool operator!() const { return !i; } bool testFlag( Enum f ) const { return i & f; } }; #define DECLARE_FLAGS(Fl) \ inline Flags<Fl::enum_type> operator|( Fl::enum_type f1, Fl::enum_type f2 ) \ { return Flags<Fl::enum_type>(f1) | f2; } \ inline Flags<Fl::enum_type> operator|( Fl::enum_type f1, Flags<Fl::enum_type> f2 ) \ { return f2 | f1; } typedef Flags<A> AFlags; typedef Flags<B> BFlags; DECLARE_FLAGS( AFlags ); DECLARE_FLAGS( BFlags ); int needA( AFlags test ) { return test; } int needB( BFlags test ) { return test; } int main() { std::cout << needA( AFlag1 | AFlag2 ) << std::endl; // geht std::cout << needB( BFlag1 | BFlag2 ) << std::endl; // geht std::cout << needA( AFlag1 | BFlag2 ) << std::endl; // geht nicht std::cout << needB( 3 ) << std::endl; // geht nicht }"geht nicht" gibts nicht

(leichte Abaenderung der Implementation der Qt-Bibliothek, also nicht mein Werk)