Можно написать класс диспетчера типа коммутатора, который отображает значение условия на целевой тип и допускает действие, которое будет выполнено только один раз, поэтому использование будет примерно таким:
Switch<Action, bool, Case<true, TYPE_A>, Case<false, TYPE_B>>(some_boolean_statement);
Реализация концепции:
#include <iostream>
#include <cstdlib>
template<auto cond, typename x_Target> struct
Case;
template<template<typename T> class x_Action, typename x_Cond, typename... x_Case>
class DispatchImpl;
template<template<typename T> class x_Action, typename x_Cond, x_Cond this_cond, typename x_Target, typename... x_Case>
class DispatchImpl<x_Action, x_Cond, Case<this_cond, x_Target>, x_Case...>
{
public: static void Dispatch(x_Cond cond)
{
if(this_cond == cond)
{
x_Action<x_Target>::Invoke();
}
else
{
DispatchImpl<x_Action, x_Cond, x_Case...>::Dispatch(cond);
}
}
};
template<template<typename T> class x_Action, typename x_Cond>
class DispatchImpl<x_Action, x_Cond>
{
public: static void Dispatch(x_Cond) {}
};
template<template<typename T> class x_Action, typename x_Cond, typename... x_Case>
void Switch(x_Cond cond)
{
DispatchImpl<x_Action, x_Cond, x_Case...>::Dispatch(cond);
}
//
template<typename T> auto getRef(void) { return T{}; }
void doStuff(int) { ::std::cout << "int" << ::std::endl; }
void doStuff(float) { ::std::cout << "float" << ::std::endl; }
template<typename x_Target> struct
Action
{
static void Invoke(void)
{
doStuff(getRef<x_Target>());
}
};
int main()
{
auto cond{false};
Switch<Action, bool, Case<true, int>, Case<false, float>>(cond);
}
онлайн-компилятор