Построение ответа Эндрю ...
Обратите внимание, что EnumSensorFamily family
должен быть известен во время компиляции.Если он неизвестен до времени выполнения, вам нужно будет написать switch
, чтобы выбрать шаблон, и вы вернетесь к тому, с чего начали.
Другой способ сделать это - с помощью шаблона Traits:
template <EnumSensorFamily family>
struct SensorTraits;
template <>
struct SensorTraits<FAM1>
{
const EnumSensorFamily kFamilyID = ExpectedFam1;
};
template <>
struct SensorTraits<FAM2>
{
const EnumSensorFamily kFamilyID = ExpectedFam2;
};
template <>
struct SensorTraits<FAM3>
{
const EnumSensorFamily kFamilyID = ExpectedFam3;
};
template <EnumSensorFamily family>
bool doTest(const StructSensorProposal& proposed)
{
return (SensorTraits<family>::kFamilyID == proposed.Fam1SensorId);
}
Если вы попытаетесь использовать doTest
с семейством датчиков, в котором отсутствует специализация по признакам, вы получите ошибку компиляции.Также обратите внимание, что вы никогда не создаете экземпляр объекта признаков, вы просто используете его определения.
Это позволяет вам повторно использовать константы, typedefs, что угодно в нескольких функциях.Кроме того, добавление нового семейства не включает в себя прочесывание всего кода в поисках каждого оператора switch
, который заботится.Все, что вам нужно сделать, это создать новую специализацию SensorTraits
.
РЕДАКТИРОВАТЬ: Вы можете сделать поле зависимым от семейства датчиков с помощью указателя на элемент :
template <>
struct SensorTraits<FAM1>
{
const EnumSensorFamily kFamilyID = ExpectedFam1;
int StructSensorProposal::*proposalField = &StructSensorProposal::fam1field;
};
// ...
template <EnumSensorFamily family>
int getProposedField(const StructSensorProposal& proposed)
{
return proposed.*SensorTraits<family>::proposalField;
}
Вы также можете ввести, скажем, typedef
для типа данных датчика:
template <>
struct SensorTraits<FAM1>
{
const EnumSensorFamily kFamilyID = ExpectedFam1;
typedef uint16_t data_type;
data_type StructSensorProposal::*proposalField = &StructSensorProposal::fam1field;
};
// ...
template <EnumSensorFamily family>
SensorTraits<family>::data_type getProposedField(const StructSensorProposal& proposed)
{
return proposed.*SensorTraits<family>::proposalField;
}
Я не проверял их;вам может понадобиться const
или static
там.