#c #c 11
#c #c 11
Вопрос:
У меня есть оператор switch, который выполняется следующим образом
switch (abc) {
case FILE_0:
lf = m_a->olf[0];
kf = m_a->pkf[0];
break;
case FILE_1:
lf = m_a->olf[1];
kf = m_a->pkf[1];
break;
.
.
default:
LOG_ERR << "Wrong type to check";
return 0;
}
Это происходит около 30 раз, и в итоге у меня получается 30 случаев в этом одном коммутаторе.
Есть ли способ сократить его в C 11? Например. с помощью шаблонов.
Комментарии:
1. Как именно определяются
FILE_0
,FILE_1
, и т.д.?2. Не забывайте
break;
, если вы остаетесь с.switch()
3. Кроме того, ваши дела проваливаются. Это намеренно?
4. посмотрите, какой последний случай, вы можете удалить весь регистр switch … и просто оставить последнее назначение
5. Я делаю здесь попытку, но является
FILE_0
ли использование элемента 0 (lf = m_a->olf[0];
) иFILE_1
использование элемента 1 (lf = m_a->olf[0];
) шаблоном? Является ли значение FILE_0 фактически 0, а FILE_1 фактически 1? Если да (или вы могли бы сделать это такlf=m_a->olf[abc]
, это ответ. Здесь недостаточно кода, чтобы действительно понять, что вы делаете.
Ответ №1:
Ваш код не настолько велик, чтобы быть уверенным в намерении, хотя, из того, что я вижу во фрагменте, вы действительно хотите преобразовать символическое значение в индекс. (Могу ли я предположить, что это перечисление?)
Что бы я сделал, так это переместил этот код в отдельную функцию:
auto fileEnumToIndex(FileEnum file) {
switch (file) {
case FILE_0: return 0;
case FILE_1: return 1;
default: __builtin_unreachable();
}
}
Ваш код, чем изменения в:
auto index = fileEnumToIndex(abc);
lf = m_a->olf[index];
kf = m_a->pkf[index];
Если FileEnum является реальным перечислением, вы можете изменить код в функции fileEnumToIndex на простой static_cast
Чтобы охватить регистр по умолчанию, вы могли бы вернуть a std::optional
и использовать std::nullopt
case для некоторой обработки ошибок. Однако, когда FileEnum является фактическим перечислением, я бы предположил обработку ошибок при определении этого значения.
Комментарии:
1. Спасибо JVApen. да, FILE_0, FILE_1 — это реальное перечисление. Я просто хочу избежать повторения случаев внутри коммутатора 29 раз, поскольку там есть шаблон. Но я не понимаю, что вы имеете в виду в последнем предложении — «Если FileEnum является реальным перечислением, вы можете изменить код в функции fileEnumToIndex на простой static_cast»
2.
return static_cast<int>(file);
поскольку числовые значения перечисления изменяются от 0 до N, если вы их не переопределяете
Ответ №2:
Вы можете создать карту abc
и индекс и использовать ее для определения индекса.
// somewhere, maybe outside functions
static const std::unordered_map<abc_type, int> table = {
{FILE_0, 0},
{FILE_1, 1},
...
};
// inside function
auto idx_itr = table.find(abc);
if (idx_itr != table.end()) {
lf = m_a->olf[*idx_itr];
kf = m_a->pkf[*idx_itr];
} else {
// default case
}
Комментарии:
1. это делает что-то совершенно другое
2. @P__JsupportswomeninPoland Да, если провал является преднамеренным.