Runtime typeswitch для списков типов в качестве переключателя вместо вложенных if'ов?
-
23-09-2019 - |
Вопрос
Это из TTL:
////////////////////////////////////////////////////////////
// run-time type switch
template <typename L, int N = 0, bool Stop=(N==length<L>::value) > struct type_switch;
template <typename L, int N, bool Stop>
struct type_switch
{
template< typename F >
void operator()( size_t i, F& f )
{
if( i == N )
{
f.operator()<typename impl::get<L,N>::type>();
}
else
{
type_switch<L, N+1> next;
next(i, f);
}
}
};
Он используется для переключения набора текста в списке наборщиков.Вопрос в том, что они делают это с помощью серии вложенных if .Есть ли способ сделать это переключение типа в виде одного оператора select вместо этого?
Спасибо!
Решение
Вам понадобится препроцессор для генерации большого switch
.Вам понадобится get<>
к поискам без операций вне привязки.Проверьте выходные данные компилятора, чтобы убедиться, что неиспользуемые случаи не выдают выходных данных, если вам не все равно;отрегулируйте по мере необходимости ;v) .
Ознакомьтесь с библиотекой Boost Preprocessor, если вы хотите преуспеть в такого рода вещах…
template <typename L>
struct type_switch
{
template< typename F >
void operator()( size_t i, F& f )
{
switch ( i ) {
#define CASE_N( N ) \
case (N): return f.operator()<typename impl::get<L,N>::type>();
CASE_N(0)
CASE_N(1)
CASE_N(2)
CASE_N(3) // ad nauseam.
}
};
Другие советы
Я так не думаю.
Этот вид шаблонного метапрограммирования обычно выполняется с помощью рекурсии.Поскольку все это происходит во время компиляции, я не удивлюсь, если не будет рекурсии во время выполнения или проверки условий.
Вы всегда можете использовать двоичный поиск вместо линейного.Это было бы сложнее и с большей вероятностью содержало бы ошибки (бинарный поиск на удивление легко испортить).
Вы также можете вручную развернуть из N type_switch::operator()
, где N - некоторая разумная верхняя граница количества длин списка типов, которые у вас будут в вашей программе.