Унификация выбора типа на этапе исполнения (run-time)

Мне нужно, чтобы конкретный тип определялся на этапе исполнения. Типов фиксированное количество, но много. Если точно, то 256. Я сделал мэйкер. Но выглядит это жутко.

static TBase* NewObj(unsigned char num)
{
    switch (num)
    {
    case 0: return new TDerived<0>;
    case 1: return new TDerived<1>;
    case 2: return new TDerived<2>;
    case 3: return new TDerived<3>;
    case 4: return new TDerived<4>;
    case 5: return new TDerived<5>;
    case 6: return new TDerived<6>;
    case 7: return new TDerived<7>;
    case 8: return new TDerived<8>;
    case 9: return new TDerived<9>;
    case 10: return new TDerived<10>;
    case 11: return new TDerived<11>;
    case 12: return new TDerived<12>;
    case 13: return new TDerived<13>;
    case 14: return new TDerived<14>;
    case 15: return new TDerived<15>;
    // ...
    // ...
    default: return nullptr;
    }
}

Можно это сделать без 256 case'ов? Или это нормально? Или я опять туплю?


Ответы (1 шт):

Автор решения: user7860670

Вместо case можно запихнуть указатели на функции в таблицу:

template<unsigned char num>
auto
MakeObj()
{ 
    return ::std::unique_ptr<TBase>{new TDerived<num>{}};
}

template<unsigned char... num_pack>
constexpr auto
MakeLut(::std::integer_sequence<unsigned char, num_pack...>)
{
    return ::std::array{&MakeObj<num_pack>...};
}

constexpr auto lut{MakeLut(::std::make_integer_sequence<unsigned char, 255>())};

auto NewObj(unsigned char num)
{
    return (*lut[num])();
}
→ Ссылка