Эмуляция перечисления Java в переполнении стека

Я портировал приложение, которое я написал некоторое время назад, с Java на C ++. Одна вещь, которую я быстро понял, заключалась в том, что богатые Java Enum (которые были введены в Java 5) намного превосходили те, что представлены в C ++. C ++ 0x и более поздние «строго типизированные перечисления» в C ++ 11 (то есть классы перечислений) по-прежнему не обеспечивают богатства, предоставляемого перечислениями Java Enums, и я не смог найти здесь ничего, чтобы эмулировать это средство.

Я намеревался попытаться эмулировать некоторые функции как отдельные классы, и я хотел бы, чтобы некоторая помощь реализовала это, возможно, с использованием шаблонов, если это уместно (просто кажется, что должен быть более общий способ реализовать это). Вы увидите, что возможность поиска определенного Enum по имени строки довольно многословно реализована (это эмуляция Java ENUM valueOf (String str) метод — это работает — но я уверен, что это далеко от оптимального. В способе, которым я реализовал экземпляры Enum, используются статические экземпляры const внутри класса — я нашел это где-то в переполнении стека — но я не могу вспомнить, где именно — извините.

К сведению, приложение представляет собой анализатор строк NMEA, и вот некоторые из наиболее интересных классов Enum:

Вот заголовок

#ifndef _NMEASentence_h_
#define _NMEASentence_h_

// SYSTEM INCLUDES
#include <stdint.h>
#include <string>

// APPLICATION INCLUDES
// DEFINES
// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
// FORWARD DECLARATIONS

/**
*  Name:  NMEASentence
*/
class NMEASentence
{
public:
static const int MAX_LEN;
static const char START;
static const char CKSM_DELIM;
static const char CR;
static const char LF;

NMEASentence(
const std::string rPrefix,
const std::string& rParams)
: mPrefix(rPrefix)
, mParams(rParams)
{};

// make the class abstract
virtual ~NMEASentence() = 0;

protected:
std::string mPrefix;
std::string mParams;
};

#endif // _NMEASentence_h_

Вот CPP

// SYSTEM INCLUDES
// APPLICATION INCLUDES
#include "vcdu/NMEASentence.h"
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS
const int NMEASentence::MAX_LEN = 82;
const char NMEASentence::START = '$';
const char NMEASentence::CKSM_DELIM = '*';
const char CR = '\r';
const char LF = '\n';

// implementation of the pure virtual dtor allowed
// its a trick to allow class to be abstract
NMEASentence::~NMEASentence()
{};

Вот подкласс общего класса NMEASentence

#ifndef _CDUMessage_h_
#define _CDUMessage_h_

// SYSTEM INCLUDES
//#include <...>

// APPLICATION INCLUDES
#include "vcdu/NMEASentence.h"#include "vcdu/CDUEnumConstants.h"
// DEFINES
// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
// FORWARD DECLARATIONS

/**
* CDUMessage
*/
class CDUMessage : public NMEASentence
{
public:
/**
* 5 classifications of message types, The type specifies the
* number and type of each parameter
*/
typedef enum CDUMessageSubType {
Alive,
Display,
XYDisplay,
Status,
Keyboard,
Configuration
} CDUMessageSubType;

/**
* enumeration of the supported message types & their arg count
*/
static class CDUMessageType {
public:
static const CDUMessageType CDUAlive;
// the following 3 messages are associated with the title line
static const CDUMessageType CDUDisplayDataStatusBlock;
static const CDUMessageType CDUDisplayTitle;
static const CDUMessageType CDUDisplayPageNumber;
// these messages are associated with the active display area
static const CDUMessageType CDUDisplayScratchPad;
static const CDUMessageType CDUDisplayLS1Text;
static const CDUMessageType CDUDisplayLS2Text;
static const CDUMessageType CDUDisplayLS3Text;
static const CDUMessageType CDUDisplayLS4Text;
static const CDUMessageType CDUDisplayLS5Text;
static const CDUMessageType CDUDisplayLS6Text;
static const CDUMessageType CDUDisplayLS1SText;
static const CDUMessageType CDUDisplayLS2SText;
static const CDUMessageType CDUDisplayLS3SText;
static const CDUMessageType CDUDisplayLS4SText;
static const CDUMessageType CDUDisplayLS5SText;
static const CDUMessageType CDUDisplayLS6SText;
static const CDUMessageType CDUDisplayRS1Text;
static const CDUMessageType CDUDisplayRS2Text;
static const CDUMessageType CDUDisplayRS3Text;
static const CDUMessageType CDUDisplayRS4Text;
static const CDUMessageType CDUDisplayRS5Text;
static const CDUMessageType CDUDisplayRS6Text;
static const CDUMessageType CDUDisplayRS1SText;
static const CDUMessageType CDUDisplayRS2SText;
static const CDUMessageType CDUDisplayRS3SText;
static const CDUMessageType CDUDisplayRS4SText;
static const CDUMessageType CDUDisplayRS5SText;
static const CDUMessageType CDUDisplayRS6SText;
// this is a special message to clear the screen buffer
static const CDUMessageType CDUDisplayCLS;
static const CDUMessageType CDUDisplayPutString;
static const CDUMessageType CDUStatus;
static const CDUMessageType CDUKeyboard;
static const CDUMessageType CDUSet;
static const CDUMessageType CDUGet;

inline std::string getPrefix() const {
return mPrefix;
}

inline CDUMessageSubType getMesageSubType() const {
return mSubType;
}

inline virtual int getTextRowIndex() const {
return mTextRowIndex;
}

inline JustifyStyle getJustifyStyle() const {
return mJustifyStyle;
}

static std::vector<CDUMessageType>& getValues() {
static std::vector<CDUMessageType> gValues;
if (gValues.empty()) {
gValues.push_back(CDUAlive);
gValues.push_back(CDUDisplayDataStatusBlock);
gValues.push_back(CDUDisplayTitle);
gValues.push_back(CDUDisplayPageNumber);
gValues.push_back(CDUDisplayScratchPad);
gValues.push_back(CDUDisplayLS1Text);
gValues.push_back(CDUDisplayLS2Text);
gValues.push_back(CDUDisplayLS3Text);
gValues.push_back(CDUDisplayLS4Text);
gValues.push_back(CDUDisplayLS5Text);
gValues.push_back(CDUDisplayLS6Text);
gValues.push_back(CDUDisplayLS1SText);
gValues.push_back(CDUDisplayLS2SText);
gValues.push_back(CDUDisplayLS3SText);
gValues.push_back(CDUDisplayLS4SText);
gValues.push_back(CDUDisplayLS5SText);
gValues.push_back(CDUDisplayLS6SText);
gValues.push_back(CDUDisplayRS1Text);
gValues.push_back(CDUDisplayRS2Text);
gValues.push_back(CDUDisplayRS3Text);
gValues.push_back(CDUDisplayRS4Text);
gValues.push_back(CDUDisplayRS5Text);
gValues.push_back(CDUDisplayRS6Text);
gValues.push_back(CDUDisplayRS1SText);
gValues.push_back(CDUDisplayRS2SText);
gValues.push_back(CDUDisplayRS3SText);
gValues.push_back(CDUDisplayRS4SText);
gValues.push_back(CDUDisplayRS5SText);
gValues.push_back(CDUDisplayRS6SText);
gValues.push_back(CDUDisplayCLS);
gValues.push_back(CDUDisplayPutString);
gValues.push_back(CDUStatus);
gValues.push_back(CDUKeyboard);
gValues.push_back(CDUSet);
gValues.push_back(CDUGet);
}
return gValues;
}
private:
CDUMessageType(const std::string& rPrefix,
const CDUMessageSubType& rSubType,
const JustifyStyle& rJustifyStyle,
const int& rTextRowIndex)
: mPrefix (rPrefix)
, mSubType (rSubType)
, mJustifyStyle(rJustifyStyle)
, mTextRowIndex(rTextRowIndex)
{}

std::string mPrefix;
CDUMessageSubType mSubType;
JustifyStyle mJustifyStyle;
int mTextRowIndex;
};

CDUMessageType getMessageType() const {
return mMessageType;
};

virtual ~CDUMessage(){};
protected:
/**
* Alternative Simplified Constructor
* @param aMessageType
* @param aParams
*/
CDUMessage(const CDUMessageType& rMessageType, const std::string& rParams)
: NMEASentence (rMessageType.getPrefix(), rParams)
, mMessageType (rMessageType)
{};

CDUMessageType mMessageType;
};

#endif // _CDUMessage_h_

И соответствующий CPP

// SYSTEM INCLUDES
//#include <...>

// APPLICATION INCLUDES
#include "vcdu/CDUMessage.h"
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STATIC VARIABLE INITIALIZATIONS
// this is the heartbeat message (not associated with any line => -1 for last paramter)
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUAlive ("PCDUALIVE", CDUMessage::Alive, JustifyStyle::Left, -1);

// the following 3 messages are associated with the title line
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayDataStatusBlock("PCDUDSB", CDUMessage::Display,  JustifyStyle::Left, 0);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayTitle("PCDUTIT", CDUMessage::Display, JustifyStyle::Center, 0);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayPageNumber("PCDUPGE", CDUMessage::Display, JustifyStyle::Right, 0);

// these messages are associated with the active display area
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayScratchPad("PCDUSPD", CDUMessage::Display,  JustifyStyle::Left, 13);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS1Text("PCDUL1T", CDUMessage::Display,  JustifyStyle::Left, 2);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS2Text("PCDUL2T", CDUMessage::Display,  JustifyStyle::Left, 4);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS3Text("PCDUL3T", CDUMessage::Display,  JustifyStyle::Left, 6);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS4Text("PCDUL4T", CDUMessage::Display,  JustifyStyle::Left, 8);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS5Text("PCDUL5T", CDUMessage::Display,  JustifyStyle::Left, 10);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS6Text("PCDUL6T", CDUMessage::Display,  JustifyStyle::Left, 12);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS1SText("PCDUL1S", CDUMessage::Display,  JustifyStyle::Left, 1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS2SText("PCDUL2S", CDUMessage::Display,  JustifyStyle::Left, 3);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS3SText("PCDUL3S", CDUMessage::Display,  JustifyStyle::Left, 5);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS4SText("PCDUL4S", CDUMessage::Display,  JustifyStyle::Left, 7);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS5SText("PCDUL5S", CDUMessage::Display,  JustifyStyle::Left, 9);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayLS6SText("PCDUL6S", CDUMessage::Display,  JustifyStyle::Left, 11);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS1Text("PCDUR1T", CDUMessage::Display, JustifyStyle::Right, 2);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS2Text("PCDUR2T", CDUMessage::Display, JustifyStyle::Right, 4);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS3Text("PCDUR3T", CDUMessage::Display, JustifyStyle::Right, 6);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS4Text("PCDUR4T", CDUMessage::Display, JustifyStyle::Right, 8);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS5Text("PCDUR5T", CDUMessage::Display, JustifyStyle::Right, 10);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS6Text("PCDUR6T", CDUMessage::Display, JustifyStyle::Right, 12);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS1SText("PCDUR1S", CDUMessage::Display, JustifyStyle::Right, 1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS2SText("PCDUR2S", CDUMessage::Display, JustifyStyle::Right, 3);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS3SText("PCDUR3S", CDUMessage::Display, JustifyStyle::Right, 5);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS4SText("PCDUR4S", CDUMessage::Display, JustifyStyle::Right, 7);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS5SText("PCDUR5S", CDUMessage::Display, JustifyStyle::Right, 9);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayRS6SText("PCDUR6S", CDUMessage::Display, JustifyStyle::Right, 11);

// these messages are not associated with a paricular line# which is why we specify -1 for the last parameter
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayCLS("PCDUCLS", CDUMessage::Display,  JustifyStyle::Left, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUDisplayPutString("PCDUPUTS", CDUMessage::XYDisplay,  JustifyStyle::None, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUStatus("PCDUSID", CDUMessage::Status,  JustifyStyle::Left, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUKeyboard("PCDUKEY", CDUMessage::Keyboard,  JustifyStyle::Left, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUSet("PCDUSETV", CDUMessage::Configuration,  JustifyStyle::Left, -1);
const CDUMessage::CDUMessageType CDUMessage::CDUMessageType::CDUGet("PCDUGETV", CDUMessage::Configuration, JustifyStyle::Left, -1);

И просто для того, чтобы показать общую схему использования Enums здесь, у нас есть некоторые другие классы Enum C ++, которые мне нужно было использовать в приложении. Все они выглядят довольно похоже, и я не могу не чувствовать, что должен быть более простой, менее многословный способ реализации этого. Любая помощь или идеи будут действительно приветствоваться.

class JustifyStyle {
public:
static const JustifyStyle Left, Center, Right, None;
inline std::string getName() const {
return mName;
}
private:
JustifyStyle(const std::string& rName)
: mName(rName)
{}
std::string mName;
};

class FontSize {
public:
static const FontSize F1, F2, F3, F4, F5, F6;
inline std::string getName() const {
return mName;
}
static std::vector<FontSize>& getValues() {
static std::vector<FontSize> gValues;
if (gValues.empty()) {
gValues.push_back(F1);
gValues.push_back(F2);
gValues.push_back(F3);
gValues.push_back(F4);
gValues.push_back(F5);
gValues.push_back(F6);
}
return gValues;
}
private:
FontSize(const std::string& rName)
: mName(rName)
{}
std::string mName;
};

class FontStyle {
public:
static const FontStyle S, B, I, U, N;
inline std::string getName() const {
return mName;
}
static std::vector<FontStyle>& getValues() {
static std::vector<FontStyle> gValues;
if (gValues.empty()) {
gValues.push_back(S);
gValues.push_back(B);
gValues.push_back(I);
gValues.push_back(U);
gValues.push_back(N);
}
return gValues;
}
inline bool operator<(const FontStyle& rhs) const {
return mName < rhs.mName;
}
private:
FontStyle(const std::string& rName)
: mName(rName)
{}
std::string mName;
};

class FontColor {
public:
static const FontColor BLACK, CYAN, RED, YELLOW, GREEN, MAGENTA, AMBER, WHITE;
inline int getValue() const {
return mValue;
}
inline std::string getValueStr() const {
return UtlStringUtils::integerToString(mValue);
}
static std::vector<FontColor>& getValues() {
static std::vector<FontColor> gValues;
if (gValues.empty()) {
gValues.push_back(BLACK);
gValues.push_back(CYAN);
gValues.push_back(RED);
gValues.push_back(YELLOW);
gValues.push_back(GREEN);
gValues.push_back(MAGENTA);
gValues.push_back(AMBER);
gValues.push_back(WHITE);
}
return gValues;
}
private:
// constructor
FontColor(const int& rValue)
: mValue(rValue)
{}
int mValue;
};

class CDUFontChar {
public:
// constructor
CDUFontChar (
const char cduChar = '\0',
const FontSize& rSize = FontSize::F3,
const std::set<FontStyle>& rStyles = std::set<FontStyle>(),
const FontColor& rColor = FontColor::WHITE)
: mCDUChar (cduChar)
, mSize (rSize)
, mFontStyles(rStyles)
, mColor(rColor)
{}

inline char getCDUChar() const {
return mCDUChar;
}

inline FontSize getSize() const {
return mSize;
}

inline std::set<FontStyle> getStyles() const {
return mFontStyles;
}

inline FontColor getColor() const {
return mColor;
}
private:
char mCDUChar;
FontSize mSize;
std::set<FontStyle> mFontStyles;
FontColor mColor;
};

7

Решение

В основном, Java enum это языковая функция, предназначенная для пересечения моста между хорошей практикой константы и плохой практикой или антипаттерном синглтона. С ++ делает enum в скучные целочисленные константы, а Java превращает их в полностью объектно-ориентированные синглтоны, но надеется, что разработчик сохранит их const— корни в уме. Так что да, вы абсолютно правы — способ портировать через использование глобальных констант C ++. Строго говоря, перечисления Java не обязательно должны быть константами, например, они могут иметь не конечные поля, но я бы (и думаю, что «это») расценил бы это как плохую практику, поэтому аналогично все методы в ваших перечислениях C ++ должны быть семантически const,

5

Другие решения

У меня была возможность усовершенствовать подход, который я использовал для имитации Java-подобных перечислений в C ++, так как я поставил вопрос о переполнении стека. Код, показанный ниже (в файле cpp заголовка и реализации) вместе с фрагментом кода, показывающим, как перечисления могут использоваться в операторе switch, — это то, что я использовал в своем коде. Тонкости заключаются в использовании интегрального оператора приведения (который в этом случае осуществляется с помощью пользовательского оператора Value, используемого следующим образом.

// integral operator cast for switch statements (cast to named enum)
inline operator const Value() const {
return mValue;
}

В заголовочном файле CDUEnumConstants.h:

#ifndef _cduEnumConstants_h_
#define _cduEnumConstants_h_

// SYSTEM INCLUDES
#include <set>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>

// APPLICATION INCLUDES
#include "util/UtlExceptions.h"#include "util/UtlStringUtils.h"
// DEFINES
// MACROS
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
class Annunciator {
public:
enum Value {
// these are all undefined in the discrete sense
undefined=-1, power=-2, fail=-3,
// these are discrete bits
exec=(1<<6), dspy=(1<<7), msg=(1<<8), ofst=(1<<9)
};
static const Annunciator AnnunciatorUNDEFINED;
static const Annunciator AnnunciatorPOWER;
static const Annunciator AnnunciatorFAIL;
static const Annunciator AnnunciatorEXEC;
static const Annunciator AnnunciatorDSPY;
static const Annunciator AnnunciatorMSG;
static const Annunciator AnnunciatorOFST;
// used to store in a set
inline bool operator<(const Annunciator& rhs) const {
return mValue < rhs.mValue;
}
// used for comparisons
inline bool operator==(const Annunciator& rhs) const {
return mValue == rhs.mValue;
}
inline bool supported() const {
return mValue > 0;
}
// integral operator cast for switch statements (cast to named enum)
inline operator const Value() const {
return mValue;
}

inline std::string getStringVal() const {
return mStringVal;
}

static const std::set<Annunciator>& getValues() {
static std::set<Annunciator> gValues;
if (gValues.empty()) {
gValues.insert(AnnunciatorUNDEFINED);
gValues.insert(AnnunciatorPOWER);
gValues.insert(AnnunciatorFAIL);
gValues.insert(AnnunciatorEXEC);
gValues.insert(AnnunciatorDSPY);
gValues.insert(AnnunciatorMSG);
gValues.insert(AnnunciatorOFST);
}
return gValues;
}
static Annunciator valueOf(const std::string& rStringVal) {
for (const auto& next : getValues()) {
if (next.getStringVal() == rStringVal) {
return next;
}
}
throw new UtlIllegalArgumentException(
"Illegal Argument: " + rStringVal);
}
private:
Annunciator(const Value& rValue, const std::string& rStringVal)
: mValue(rValue)
, mStringVal(rStringVal)
{}
Value mValue;
std::string mStringVal;
};// FORWARD DECLARATIONS

// Extendable in the future
class CDUVariable {
public:
enum Value {
baud, firmware, type, serial
};
static const CDUVariable Baud, Firmware, Type, Serial;
// used to store in a set
inline bool operator<(const CDUVariable& rhs) const {
return mValue < rhs.mValue;
}
// used for comparisons
inline bool operator==(const CDUVariable& rhs) const {
return mValue == rhs.mValue;
}
// integral operator cast for switch statements (cast to named enum)
inline operator const Value() const {
return mValue;
}
inline std::string getStringVal() const {
return mStringVal;
}
static const std::set<CDUVariable>& getValues() {
static std::set<CDUVariable> gValues;
if (gValues.empty()) {
gValues.insert(Baud);
gValues.insert(Firmware);
gValues.insert(Type);
gValues.insert(Serial);
}
return gValues;
}
static CDUVariable valueOf(const std::string& rStringVal) {
for (const auto& next : getValues()) {
if (next.getStringVal() == rStringVal) {
return next;
}
}
throw new UtlIllegalArgumentException(
"Illegal Argument: " + rStringVal);
}
private:
CDUVariable(const Value& rValue, const std::string& rStringVal)
: mValue(rValue)
, mStringVal(rStringVal)
{}
Value mValue;
std::string mStringVal;
};

#endif // _cduEnumConstants_h_

и в реализации CDUEnumConstants.cpp файл, в котором инициализируются начальные значения перечислений.

const Annunciator Annunciator::AnnunciatorUNDEFINED(Annunciator::undefined, "UNDEFINED");
const Annunciator Annunciator::AnnunciatorPOWER(Annunciator::power, "POWER");
const Annunciator Annunciator::AnnunciatorFAIL(Annunciator::fail, "FAIL");
const Annunciator Annunciator::AnnunciatorEXEC(Annunciator::exec, "EXEC");
const Annunciator Annunciator::AnnunciatorDSPY(Annunciator::dspy, "DSPY");
const Annunciator Annunciator::AnnunciatorMSG(Annunciator::msg, "MSG");
const Annunciator Annunciator::AnnunciatorOFST(Annunciator::ofst, "OFST");

const CDUVariable CDUVariable::Baud(CDUVariable::baud, "0");
const CDUVariable CDUVariable::Firmware(CDUVariable::firmware, "1");
const CDUVariable CDUVariable::Type(CDUVariable::type, "2");
const CDUVariable CDUVariable::Serial(CDUVariable::serial, "3");

Теперь использовать CDUVariable enum в операторе switch в коде пользователя (игнорируйте другие подробности метода), используйте следующее.

std::unique_ptr<EngravityMessage>
VCDUManager::getConfigValue(
const CDU_ID& rCduID,
const std::unique_ptr<EngravityMessage>& rVarNameMessage)
{
EngravityConfigMessage* pVariableName =
static_cast<EngravityConfigMessage*>(rVarNameMessage.get());
gpLogManager->add(FAC_PROCESS, PRI_NOTICE,
"CDU_%d: getConfigValue\n", rCduID);
CDUVariable variable = pVariableName->getCDUVariable();
std::unique_ptr<EngravityMessage> variableValue;
switch (variable) {
case CDUVariable::baud:
variableValue = std::unique_ptr<EngravityMessage>(
new EngravityConfigMessage (
EngravityMessageType::SetV, variable, "38400"));
break;
case CDUVariable::firmware:
variableValue = std::unique_ptr<EngravityMessage>(
new EngravityConfigMessage (
EngravityMessageType::SetV, variable, "1.04"));
break;
case CDUVariable::type:
variableValue = std::unique_ptr<EngravityMessage>(
new EngravityConfigMessage (
EngravityMessageType::SetV, variable, "737-NG"));
break;
case CDUVariable::serial:
variableValue = std::unique_ptr<EngravityMessage>(
new EngravityConfigMessage (
EngravityMessageType::SetV, variable, "0074"));
break;
default:
break;
}
return variableValue;
}

Я предоставил 2 примера Enums по 2 причинам, во-первых, я хотел показать, как искать значение Enum из строки, которая оптимизирована для использования отсортированного набора, и, во-вторых, шаблон здесь, кажется, намекает на программирование шаблонов — но я не было возможности реализовать его в качестве шаблона — на самом деле я не уверен, что это возможно.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector