из строки в enum

Тема в разделе "LANGS.C", создана пользователем tid, 13 сен 2011.

  1. tid

    tid Member

    Публикаций:
    0
    Регистрация:
    2 дек 2010
    Сообщения:
    57
    встала задача разработать класс который сопоставляет строку, аналогичному enum'у. причем задача должна
    решаться в самом общем виде.
    т.е. сапоставлять по switch'у нельзя.
    вобщем есть
    template<typename EnumType>class EnumsJob
    {
    public:

    int getenumbyname(const char* str)
    {
    // ???
    }
    };

    ничего умнее это не придумал. а это не решение.
    #ifndef _ENUMJOB
    #define _ENUMJOB

    #define stringify( name ) # name
    #endif

    enum color {
    RED,
    BLUE,
    GREEN
    };

    const char* colors[] = {
    stringify (RED),
    stringify (BLUE),
    stringify (GREEN)
    };

    template<typename EnumType>class EnumsJob
    {
    private:

    EnumType en;

    public:

    int getenumbyname(const char* str)
    {
    int dwIndex;
    dwIndex = 0;
    while (colors[dwIndex])
    {
    if (strcmp(str, colors[dwIndex]) == 0)
    {
    return dwIndex;
    }
    dwIndex++;
    }
    }
    };
     
  2. tid

    tid Member

    Публикаций:
    0
    Регистрация:
    2 дек 2010
    Сообщения:
    57
    Вообще ясно конечно, что тут нужно как то жутко поизвращаться с макросами. Но вот как это вопрос.
     
  3. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    задача странная, да и вы не понимаете... элемент enum - это константа времени компиляции, строка - это последовательность символов... единственная возможность реализовать подобное: элементы enum - хеш-значения строк, при этом хеш строки должен вычисляться на этапе компиляции... на этапе выполнения хеш, посчитанный тем же алгоритмом, будет являться индексом элемента enum... такое вполне возможно реализовать только на компиляторе с поддержкой C++0x, конкретно либо constexpr, либо шаблоны с переменным числом параметров... а на данный момент это наверное только gcc старше версии 4.5 (под виндой mingw с gcc соответствующей версии)...

    ЗЫ макросами никак не сделать...
    ЗЗЫ ну или можно сделать по тупому: вместо enum использовать N-дефайнов с вычисленными заранее значениями хешей...
     
  4. kam1

    kam1 New Member

    Публикаций:
    0
    Регистрация:
    26 июн 2011
    Сообщения:
    10
    Можно сделать, используя RTTI для этого. Нужно определять [имя_объекта].name() - строковое представление имени объекта и сопоставлять с вводимой строкой. Правда, генерация таких имён зависит от компилятора.
     
  5. tid

    tid Member

    Публикаций:
    0
    Регистрация:
    2 дек 2010
    Сообщения:
    57
    Rel
    задача странная да еще какая это как раз так и понятно. так же понятно что из себя представляет enum.

    вопрос вопрос в том как извратиться с макросами что бы они скажем генерировали мне хотя бы вот то что я написал руками.

    const char* colors[] = {
    stringify (RED),
    stringify (BLUE),
    stringify (GREEN)
    };

    я тоже решения не вижу и кажется единственным вариантом сделать словарь map<String, EnumType> abc; и в ручную его заполнять. но это не решение.
     
  6. tid

    tid Member

    Публикаций:
    0
    Регистрация:
    2 дек 2010
    Сообщения:
    57
    kam1
    интересно, только не совсем понятно как я смогу получить названия полей в enum'e. так я только выясню что это enum с именем color и всё.
     
  7. tid

    tid Member

    Публикаций:
    0
    Регистрация:
    2 дек 2010
    Сообщения:
    57
    #include <iostream>

    enum color {
    RED,
    BLUE,
    GREEN
    } sd;

    int main()
    {
    std::cout << typeid(sd).name() << '\n';
    return 0;
    }

    на экране я получу:
    enum color
     
  8. kam1

    kam1 New Member

    Публикаций:
    0
    Регистрация:
    26 июн 2011
    Сообщения:
    10
  9. tid

    tid Member

    Публикаций:
    0
    Регистрация:
    2 дек 2010
    Сообщения:
    57
    там мрак:
    Код (Text):
    1. enumeration_begin(color)
    2. declare_member(RED) delimiter
    3. declare_member(GREEN) delimiter
    4. declare_member(BLUE)
    5. enumeration_end;
    тогда уж сразу юзать словарь и не мучить себя.
    это не решение.
     
  10. tid

    tid Member

    Публикаций:
    0
    Регистрация:
    2 дек 2010
    Сообщения:
    57
    на rsdn есть интересная статья называется "Строгие перечисления в С++", задача там конечно не решается в поставленном виде. но в целом достаточно интересно.