Usando enumeraciones de una clase (C++)

Estoy usando una biblioteca que tiene clases con varias enumeraciones. aquí hay un ejemplo

class TGNumberFormat
{
  public:
  // ...
  enum EAttribute {   kNEAAnyNumber
    kNEANonNegative
    kNEAPositive
  };
  enum ELimit {   kNELNoLimits
    kNELLimitMin
    kNELLimitMax
    kNELLimitMinMax
  };
  enum EStepSize {   kNSSSmall
    kNSSMedium
    kNSSLarge
    kNSSHuge
  };
  // etc...
};

En el código tengo que referirme a estos como TGNumberFormat::kNEAAnyNumber por ejemplo. Estoy escribiendo una GUI que usa estos valores muy a menudo y el código se está poniendo feo. ¿Hay alguna forma en que pueda importar estas enumeraciones y simplemente escribir kNEAAnyNumber? Realmente no espero que ninguno de estos nombres se superponga. He probado varias formas de usar el using palabra clave y ninguno compilará.

preguntado el 12 de junio de 12 a las 20:06

Yo usaría un typedef local para la función (por ejemplo, typedef TGNumberFormat NF;, permitiendo, por ejemplo, NF::kNELLimitMin). Sin embargo, diría que es mejor escribir los nombres. -

struct X : TGNumberFormat {};. Entonces puedes usarlos como X::kNEAAnyNumber. No te recomiendo que hagas esto, ya que TGNumberFormat (aparentemente) tiene más significado que cualquier nombre más corto que se te ocurra para X. -

4 Respuestas

Si usa estas constantes en todo su código, podría ser beneficioso crear su propio encabezado que redefina los valores en un espacio de nombres. entonces puedes using ese espacio de nombres. No necesita redefinir todos los valores, solo los nombres de los enumeradores. Por ejemplo,

namespace TGEnumerators
{
    static EAttribute const kNEAAnyNumber(TGNumberFormat::kNEAAnyNumber);
    // etc.
}

Alternativamente, puede escribir def TGNumberFormat a un nombre más corto en las funciones o archivos de origen donde lo usa con frecuencia. Por ejemplo,

typedef TGNumberFormat NF;
NF::EAttribute attribute = NF::kNEAAnyNumber;

Yo diría que el último enfoque es superior y, si se usa juiciosamente en el alcance del bloque, es una buena práctica. Sin embargo, para usar en un archivo, creo que sería preferible usar los nombres completos de los enumeradores, para mayor claridad.

Respondido el 12 de junio de 12 a las 21:06

+1 No puedo contar cuántas veces vi un enumerador simple y me pregunté de dónde diablos vino porque estaba escondido por un astuto typedef or using. - mark B

Solo una pequeña observación: para la redefinición de valores (su primer método), creo que es mejor usar static const EAttribute en lugar de simple EAttribute. - sinxis

@Mark Para dejar en claro que el enlace es interno. No es necesario que el código funcione, pero creo que es más autodescriptivo. - sinxis

Otra forma posible, pero implica un poco más de trabajo por adelantado, es definir un lote de constantes que luego usará en su lugar:

p.ej

const TGNumberFormat::EAttribute AnyNumber = TGNumberFormat::kNEAAnyNumber;
const TGNumberFormat::EAttribute NonNegative = TGNumberFormat::kNEANonNegative;
...

attribute = AnyNumber;

Respondido el 12 de junio de 12 a las 21:06

Si usa c ++ 11, puede usar la palabra clave auto para deducir el tipo:

//the compiler will see auto and know to use: TGNumberFormat::EAttribute
auto attribute = TGNumberFormat::kNEAAnyNumber;

compilado con: g++ -std=c++0x -o main main.cpp

Si no está usando c++ 11, considere usar typedefs como lo menciona @James McNellis
No se recomienda el uso de macros porque no obedecerán las reglas del alcance; los typedefs sí lo harán.

Respondido el 12 de junio de 12 a las 21:06

Dos soluciones:

  1. Vive con ello.
  2. #define AnyNumber TGNumberFormat::kNEAAnyNumber

*Corre a cubrirse...*

Respondido el 12 de junio de 12 a las 22:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.