Как вы думаете, что произойдет в этом случае?
TYPE t = DOUBLE;
if (rand() % 2 == 0) {
t = INT;
}
int i = foo.get<int>(t); // t might be INT or DOUBLE
Это не имеет смысла, поскольку параметр TYPE
является значением времени выполнения, и вы полагаетесь на него, чтобы выбрать тип возвращаемого значения, который должен быть известен во время компиляции.
Кроме того, когда вы делаете оператор switch
, компилятор имеет для компиляции всего оператора switch, даже в тех случаях, которые могут не вызываться.
Представьте, что создается экземпляр функции-члена get<int>
:
template<>
auto get<int>(TYPE type) -> int {
switch (type) { // type might be anything
case INT:
return i; // return int
case DOUBLE:
return d; // return double
case DOUBLE2:
return d2; // return double
case STRING:
return s; // return string
}
}
Это не может скомпилироваться. Функция явно возвращает int
, но в некоторых ветвях она возвращает другие типы.
Правильным решением было бы полностью удалить перечисление и использовать что-то вроде constexpr if
для обозначения ветви времени компиляции, и вместо того, чтобы отправлять как имя, так и значение, полагаться только на имя типа.
Если вы хотите больше узнать о том, как реализовать такую структуру данных, я предлагаю вам прочитать std::tuple