Russian Qt Forum
Ноябрь 22, 2024, 22:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: С++ статик поля  (Прочитано 24087 раз)
AzazelloAV
Гость
« : Октябрь 07, 2015, 17:16 »

Это вечная тема, к которой я возращаюсь через некоторое время и решаю заново, что порядком надоело.

Чтобы небыло недопонимания, опишу лучше задачу. Как вы уже поняли, меня не интересует решение проблемы как таковой, меня интересует решение раз и навсегда.
Итак задача.

Есть некое перечисление. Мы заворачиваем это перечиление в класс (читайте в namespace),. Пишу "идеальный для меня" код.

Код:
class TagStatus {
public:
     enum Status {
         NoDefine,
         Define1,
        ......
     }
     static String convertToString(Status)
     static Status convertToEnum(String)
private:
    static StatusStr mStatusStr[3] = {"not define", "Что то стринг", ...}  
}

Где, где эту грёбанную mStatusStr, кроме как в конструкторе на проверку размера инициализировать, без отрыва от класса.

Как вы поняли, я просто прячу перечисление в класс и "прикидываюсь" что это обычное перечисление, понятно, перегрузку операторов всяких я опустил тут.

Яркий пример - QVariant::typeToName, только не отсылать к исходникам, там у них задачи посложней.

P.S. constexpr не валидно для строк.

P.S.2 Наверное сложно изьясняюсь, но задача следующая превратить перечиление в корабль, с преобразованием строки в перечисление и наоборот.

P.S.3 Никоим образом эта тема не пересекается с прятаньем приватов в C++ файлы. Разный посыл.
« Последнее редактирование: Октябрь 07, 2015, 18:01 от AzazelloAV » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #1 : Октябрь 07, 2015, 17:42 »

А std::map здесь не подходит?
Записан
AzazelloAV
Гость
« Ответ #2 : Октябрь 07, 2015, 17:55 »

А std::map здесь не подходит?

В данном контексте мап и доступ по индексу не отличается.
Ну а второй вопрос (следующий из топика) - как мне инициализировать map значениями
Записан
Johnik
Крякер
****
Online Online

Сообщений: 339


Просмотр профиля
« Ответ #3 : Октябрь 07, 2015, 18:24 »

Красиво можно решить на макросах. На макросах буста сделать это относительно просто.

P.S. Не надо обсуждать насколько красивым может быть решение на макросах, это же касается и буста. Использовать или не использовать макросы и/или буст решает каждый сам для себя.
P.P.S. AzazelloAV, если заинтересует - могу привести
Записан
AzazelloAV
Гость
« Ответ #4 : Октябрь 07, 2015, 18:49 »

Красиво можно решить на макросах. На макросах буста сделать это относительно просто.

На макросах нельзя. Я превращаю переменную в класс. Представте сотни "переменных" на макросах, тогда лучше вообще отказаться от этой идеи и идти классическим путём. Этож какая нечитаемая простыня будет....
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #5 : Октябрь 07, 2015, 18:52 »

Цитировать
Красиво можно решить на макросах.
Да, это как раз X-макросы..

Код
C++ (Qt)
namespace TagStatus {
 
#define STATUS                  \
   X(NoDefine, "NoDefine")     \
   X(Define1, "Define1")      \
   X(Define2, "Define2")
 
 
#define X(a, b) a,
   enum Status { STATUS };
#undef X
 
 
#define X(a, b) b,
   static const char * mStatusStr[] = { STATUS };
#undef X
 
}
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Johnik
Крякер
****
Online Online

Сообщений: 339


Просмотр профиля
« Ответ #6 : Октябрь 07, 2015, 19:02 »

На макросах нельзя. Я превращаю переменную в класс. Представте сотни "переменных" на макросах, тогда лучше вообще отказаться от этой идеи и идти классическим путём. Этож какая нечитаемая простыня будет....

Выглядит примерно так:
Код:
ENUM(TestEnum, (v1) (v2) (v3));
Записан
AzazelloAV
Гость
« Ответ #7 : Октябрь 07, 2015, 19:04 »

Цитировать
Красиво можно решить на макросах.
Да, это как раз X-макросы..

Код
C++ (Qt)
namespace TagStatus {
 
#define STATUS                  \
   X(NoDefine, "NoDefine")     \
   X(Define1, "Define1")      \
   X(Define2, "Define2")
 
 
#define X(a, b) a,
   enum Status { STATUS };
#undef X
 
 
#define X(a, b) b,
   static const char * mStatusStr[] = { STATUS };
#undef X
 
}
 

Э нет ребят, мы в какой-то камменый век скатываемся. Этож всего лишь частное решение, а вы его как всегда в лоб. Вы хотите все определить "компиле тайм" макросами, которые нельзя теститовать (и так далее и так далее). Конечно, можно написать шаблоны для всех этих классов, только вот засада какая - их написание перекроет задачу и причём эти шаблоны никому не нужны, кроме меня. Т.е. пиши шаблоны, но забудь про проект, пиши макросы, но задудь про изменения.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #8 : Октябрь 07, 2015, 19:13 »

Цитировать
Этож всего лишь частное решение,
Нет, оно как раз более общее, чем руками проделывать то, что вы вначале привели.

X-макросы позволяют лекго удалять, добавлять новые элементы перечисления. Причём в одном месте. Дальше всё автоматически подставиться)

 
Цитировать
макросами, которые нельзя теститовать (и так далее и так далее).
Вы о чём? Что именно здесь нельзя тестировать?
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Johnik
Крякер
****
Online Online

Сообщений: 339


Просмотр профиля
« Ответ #9 : Октябрь 07, 2015, 19:13 »

Тогда напишите Wizard(или скрипт какой...), который за вас всю подноготную нагенерит.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #10 : Октябрь 07, 2015, 20:03 »

Я про такой вариант
Код
C++ (Qt)
class TagStatus {
public:
    enum Status {
        NoDefine,
        Define1,
        Define2
    };
    static String convertToString(Status);
    static Status convertToEnum(String);
private:
   static const std::map<Status, String> mStatusStr;
};
 
const std::map<TagStatus::Status, String> TagStatus::mStatusStr = {
   {NoDefine, "not define"},
   {Define1,  "Что то стринг"},
   {Define2,  "..."}
};
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Октябрь 08, 2015, 08:49 »

Я про такой вариант
Не знаю как С++11, но "до того" такая инициализация мапы не пройдет, нужно объявлять конструктор. Поиск "по строке" мапа тоже не решает, его каждый раз придется дописывать. Все это не смертельно, но возня которой, полагаю, ребятенок хотел избежать.  Вообще мапа здесь не очень, тех эл-тов макс десятки, просто перебор вполне приемлем. Я делал так
Код
C++ (Qt)
typedef QPair <const char *, SInt32> TNameType;  // тут по-хорошему нужны темплейт аргументы
 
struct CPairTable : public QList <TNameType> {
SInt32 Name2Type ( const QString & name ) const;
QString Type2Name ( SInt32 ID ) const;
QString PrintError ( const QString & badName ) const;
int IndexOfName ( const QString & name ) const;
int IndexOfType ( SInt32 ID ) const;
 
template <class T>    
CPairTable & operator << ( const T & value )  // чтобы добавлять эл-ты в объявлении const
{
return (CPairTable &) (QList <TNameType>::operator << (value));
}
};
 
« Последнее редактирование: Октябрь 08, 2015, 08:50 от Igors » Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #12 : Октябрь 08, 2015, 09:17 »

С макросами костыль конечно аццкий  Подмигивающий

Но имхо другое еще хуже...
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Октябрь 08, 2015, 09:30 »

Вот интересное на мой взгляд решение https://github.com/flaub/boost-enum:
Код
C++ (Qt)
BOOST_ENUM(Level,
   (Abort)("unrecoverable problem")
   (Error)("recoverable problem")
   (Alert)("unexpected behavior")
   (Info)("expected behavior")
   (Trace)("normal flow of execution")
   (Debug)("detailed object state listings")
)
 
int main()
{
   foreach(const string& name, Level::names)
   {
       cout << name << endl;
   }
   cout << "1: " << Level::names[1] << endl;
   cout << "toString(Abort): " << Level::toString(Level::Abort) << endl;
   cout << "getValue(Abort): " << Level::getValue(Level::Abort) << endl;
 
   Level::type value = Level::Invalid;
   bool ret = Level::fromString("Abort", value);
   cout << "fromString(\"Abort\"): " << ret << ", " << value << endl;
 
   value = Level::Invalid;
   ret = Level::fromString("Debug", value);
   cout << "fromString(\"Debug\"): " << ret << ", " << value << endl;
 
   value = Level::Invalid;
   ret = Level::fromString("not in enum", value);
   cout << "fromString(\"not in enum\"): " << ret << ", " << value << endl;
 
   return 0;
}
 

Цитировать
Abort
Error
Alert
Info
Trace
Debug
Invalid
1: Error
toString(Abort): Abort
getValue(Abort): unrecoverable problem
fromString("Abort"): 1, 0
fromString("Debug"): 1, 5
fromString("not in enum"): 0, 6
Записан
AzazelloAV
Гость
« Ответ #14 : Октябрь 08, 2015, 12:57 »

Нашёл простое решение, которое подходит для меня

Код
C++ (Qt)
class TagStatus {
public:
    enum Status {
        NoDefine,
        Define1,
        Define2
    };
    static String convertToString(Status);
    static Status convertToEnum(String);
private:
   static class HashStr: public<String,enum> {
        HashStr() {
            insert("Not define",NoDefine);
            ......
        }
   } mHashStr;
};
 

Конечно, код у меня другой, но смысл понятен.
Вот тут уже можно подумать написать один шаблон для всех классов

Цитировать
Вот интересное на мой взгляд решение https://github.com/flaub/boost-enum:
Цитировать
Решение такое я думаю тоже подойдёт. Я все таки его не исследовал, поэтому однозначного ответа дать не могу.


« Последнее редактирование: Октябрь 08, 2015, 13:34 от AzazelloAV » Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.436 секунд. Запросов: 23.