Ну, вы могли бы извлечь приведения:
int64_t loadptr_uint8(const void *p) {
return *(uint8_t*)p;
}
int64_t convert_uint8(int64_t val) {
return (uint8_t)val;
}
int testLimits(const limits_t *plimits, const void *pData, int64_t(*loadptr)(void*), int64_t (*convert)(int64_t)) {
return loadptr(pData) <= convert(limits->max) && loadptr(pData) >= convert(limits->min);
}
switch(key->type) {
case TYPE_UINT8:
isWithinLimits = testLimits(&limits, pData, loadptr_uint8, convert_uint8);
break;
// etc
}
Или, если различные типы образуют непрерывный диапазон значений от 0, вы можете даже создать два массива указателей на функциии выполните:
bool isWithinLimits = testLimits(&limits, pData, loadptrs[key->type], converts[key->type]);
Примечания:
- Вам все еще нужно написать две функции для каждого типа, хотя они легко генерируются макросом, если вы предпочитаете.
- Кажется, для этого небольшого кода оно того не стоит.
- Я выбрал
int64_t
, поскольку он способен представлять все значения всех целочисленных типов, которые вы используете, поэтому преобразования в int64_t
никогда не сбрасывает информацию и никогда не изменяет результат сравнения по сравнению с выполнением того же сравнения в типе источника.Но если вы также хотите охватить uint64_t
, то вы не можете использовать один и тот же тип для всего, поскольку нет целочисленного типа, который мог бы представлять все значения всех целочисленных типов.Вам также понадобится отдельная функция testLimitsf
для float
, возможно, использующая long double
в качестве общего типа для будущей гибкости. - [Редактировать: я только что понял, предполагая IEEE-754,
double
на самом деле может точно представлять все значения всех типов, которые вы используете.Таким образом, с небольшим ограничением переносимости, вы можете использовать testLimitsf
для всего и иметь дело с двойными числами] - Вы уверены, что стоит сравнить (например) с
uint8_t
перед сравнением?Либо значение находится в диапазоне для uint8_t
, и в этом случае вам не нужно конвертировать, вы можете просто сделать сравнение.Или же значение не находится в диапазоне, и в этом случае уменьшение по модулю делает сравнение немного бессмысленным, за исключением особых случаев 0 и -1.Так что это может стоить того, если что-то, что вы не заявили, делает это так, но мне это кажется подозрительным. - Вы сказали в комментарии: «Я пытаюсь сделать эту функцию более эффективной».Это может пойти против этого.Логически возможно встроить
testLimits
, а также вызовы функций приведения в switch
, но я бы на это не рассчитывал.