Мы можем использовать дополнительный параметр для создания различных перегрузок в зависимости от типа, а затем использовать разрешение перегрузки, чтобы найти нужную функцию.TypeTag
- это пустой класс, который мы можем использовать для различения различных перегрузок:
template<class T>
struct TypeTag{ /* empty */ };
Получив это, мы можем написать read_as
функций на основе тега:
int read_as(xml_attribute param, TypeTag<int>) {
return param.as_int();
}
bool read_as(xml_attribute param, TypeTag<bool>) {
return param.as_bool();
}
float read_as(xml_attribute param, TypeTag<float>) {
return param.as_float();
}
double read_as(xml_attribute param, TypeTag<double>) {
return param.as_double();
}
const pugi::char_t* read_as(xml_attribute param, TypeTag<const pugi::char_t*) {
return param.as_string();
}
Создание универсального шаблона теперь довольно просто:
template<class T>
T read_as(xml_attribute param) {
return read_as(param, TypeTag<T>());
}
Это решение работает на C ++ 11 и будет компилироваться быстрее, чем серия if constexpr
проверок, потому что компилятор может найти правильную версиючерез разрешение перегрузки, вместо того, чтобы выполнять серию проверок.