Как сказал Нил, я никогда не сталкивался с проблемой сам.Хотя я столкнулся с проблемой кодовых наборов (т.е. сопоставление строки с перечислением и обратно).
Моя первая реакция - эпидермальная: DRY.
Как вы заметили, поддержание двух перечислений иперевод требует времени, поэтому лучше провести рефакторинг и использовать только один.
Моя вторая реакция - попытаться удалить перечисление.Я не люблю перечисления.Возможно, я буду признателен за них с выходом C ++ 0x, но в их нынешнем виде они доставляют больше хлопот, чем они того стоят.Я предпочитаю умные объекты с категориями и т. Д.
Но сама проблема, я думаю, забавная.Так что, если вам нравится справляться с этой беспорядочной ситуацией, я мог бы также попытаться облегчить вашу ношу.Я использовал их для проверки диапазона перечислений, а также для преобразования строк (туда и обратно) и итераций, но это все, что они могут сделать.Однако, как вы и подозревали, это возможно с некоторым «тонким» приложением Boost.Preprocessor.
Что вы хотели бы написать:
DEFINE_CORRESPONDING_ENUMS(Server, Client,
((Server1, 1, Client1, 6))
((Server2, 2, Client2, 3))
((Common1, 4, Common1, 4))
((Common2, 5, Common2, 5))
((Server3, 7, Client3, 1))
);
И мы бы хотели, чтобы оно генерировало:
struct Server
{
enum type { Server1 = 1, Server2 = 2, Common1 = 4, Common2 = 5, Server3 = 7 };
};
struct Client
{
enum type { Client1 = 6, Client2 = 3, Common1 = 4, Common2 = 5, Client3 = 1 };
};
Server::type ServerFromClient(Client::type c)
{
switch(c)
{
case Client1: return Server1;
//...
default: abort();
}
}
Client::type ClientFromServer(Server::type s)
{
//...
}
Хорошая новость в том, что это возможно.Я мог бы даже сделать это, хотя я, вероятно, позволю вам немного поработать над этим;)
Вот некоторые объяснения:
- Третий элемент макроса - это последовательность.Последовательность имеет неограниченный размер.
- Каждый элемент последовательности представляет собой 4-кортеж.Вы должны знать его размер заранее, таким образом, повторение для
Common
.Если бы вы использовали последовательность вместо этого, вы могли бы иметь дело с переменным количеством элементов (например, чтобы избежать повторения общего ...), но это усложнило бы ситуацию - Вам нужно будет взглянуть на
BOOST_PP_SEQ_FOREACH
, здесь это будет основная операция. - Не забудьте
BOOST_PP_CAT
для обработки конкатенации токенов. - на
gcc
опция -E
дает выход препроцессора, это может пригодиться ... - не забывайте комментарии и как использовать в файле, ваши коллеги будут ненавидеть вас в противном случае