sobrecarga sencillos relacionales operadores operador metodos matrices ejemplos definicion c++ c++11 enums operator-overloading bitwise-operators

relacionales - sobrecarga de operadores en c++ ejemplos sencillos



¿Cómo sobrecargar |=operador en enumeración de alcance? (3)

Al combinar valores distintos para crear valores nuevos e indefinidos, contradice totalmente el paradigma de tipificación fuerte.

Parece que está configurando bits de bandera individuales que son completamente independientes. En este caso, no tiene sentido combinar sus bits en un tipo de datos donde dicha combinación produce un valor indefinido.

Debes decidir el tamaño de tus datos de bandera ( char , short , long , long long ) y rodar con ellos. Sin embargo, puede usar tipos específicos para probar, establecer y borrar marcas:

typedef enum { PadWithZero = 0x01, NegativeSign = 0x02, PositiveSign = 0x04, SpacePrefix = 0x08 } Flag; typedef short Flags; void SetFlag( Flags & flags, Flag f ) { flags |= static_cast<Flags>(f); } void ClearFlag( Flags & flags, Flag f ) { flags &= ~static_cast<Flags>(f); } bool TestFlag( const Flags flags, Flag f ) { return (flags & static_cast<Flags>)(f)) == static_cast<Flags>(f); }

Esto es muy básico y está bien cuando cada indicador es solo un bit. Para banderas enmascaradas, es un poco más complejo. Hay formas de encapsular banderas de bits en una clase fuertemente tipada, pero realmente tiene que valer la pena. En tu caso, no estoy convencido de que lo sea.

¿Cómo puedo sobrecargar el operador |= en una enum fuertemente tipificada (con alcance) (en C ++ 11, GCC)?

Quiero probar, configurar y borrar bits en enumeraciones fuertemente tipadas. ¿Por qué tipear fuertemente? Porque mis libros dicen que es una buena práctica. Pero esto significa que tengo que static_cast<int> todas partes. Para evitar esto, sobrecargo el | y & operadores, pero no puedo descubrir cómo sobrecargar al operador |= en una enumeración . Para una clase, simplemente pondrías la definición de operador en la clase , pero para enumeraciones que no parecen funcionar sintácticamente.

Esto es lo que tengo hasta ahora:

enum class NumericType { None = 0, PadWithZero = 0x01, NegativeSign = 0x02, PositiveSign = 0x04, SpacePrefix = 0x08 }; inline NumericType operator |(NumericType a, NumericType b) { return static_cast<NumericType>(static_cast<int>(a) | static_cast<int>(b)); } inline NumericType operator &(NumericType a, NumericType b) { return static_cast<NumericType>(static_cast<int>(a) & static_cast<int>(b)); }

La razón por la que hago esto: esta es la forma en que funciona en C # fuertemente tipificada: enumeración, solo hay una estructura con un campo de su tipo subyacente, y un montón de constantes definidas en él. Pero puede tener cualquier valor entero que encaje en el campo oculto de la enumeración.

Y parece que las enumeraciones de C ++ funcionan de la misma manera. En ambos idiomas, se requiere que los lanzamientos pasen de enum a int o viceversa. Sin embargo, en C # los operadores bitwise están sobrecargados de forma predeterminada, y en C ++ no lo están.


Esto parece funcionar para mí:

NumericType operator |= (NumericType &a, NumericType b) { unsigned ai = static_cast<unsigned>(a); unsigned bi = static_cast<unsigned>(b); ai |= bi; return a = static_cast<NumericType>(ai); }

Sin embargo, aún puede considerar la definición de una clase para su colección de bits de enum :

class NumericTypeFlags { unsigned flags_; public: NumericTypeFlags () : flags_(0) {} NumericTypeFlags (NumericType t) : flags_(static_cast<unsigned>(t)) {} //...define your "bitwise" test/set operations };

Entonces, cambia tu | y los operadores & para devolver NumericTypeFlags en NumericTypeFlags lugar.


inline NumericType& operator |=(NumericType& a, NumericType b) { return a= a |b; }

¿Esto funciona? Compilar y ejecutar: (Ideone)

#include <iostream> using namespace std; enum class NumericType { None = 0, PadWithZero = 0x01, NegativeSign = 0x02, PositiveSign = 0x04, SpacePrefix = 0x08 }; inline NumericType operator |(NumericType a, NumericType b) { return static_cast<NumericType>(static_cast<int>(a) | static_cast<int>(b)); } inline NumericType operator &(NumericType a, NumericType b) { return static_cast<NumericType>(static_cast<int>(a) & static_cast<int>(b)); } inline NumericType& operator |=(NumericType& a, NumericType b) { return a= a |b; } int main() { // your code goes here NumericType a=NumericType::PadWithZero; a|=NumericType::NegativeSign; cout << static_cast<int>(a) ; return 0; }

imprimir 3.