determining variadic template arguments are compile time

Advertisements

Let’s assume i want to define a type that depends on some types:

    struct TimerPump{};
    struct GuiPump{};
    struct NetworkPump{};
    
    template<class... Pumps>
    class DispatcherT{};
    
    using Dispatcher = DispatcherT< TimerPump, GuiPump, NetworkPump >;

I would like to make the gui and network pumps be optional. Either one might be needed or both or none. I could write a preprocessor macro:

using Dispatcher = DispatcherT< TimerPump
#ifdef GUI_ENABLED
                                , GuiPump
#endif
#ifdef NETWORK_ENABLED
                                , NetworkPump 
#endif
>;

but i’m looking for a way to control those arguments through traits

struct Traits
{
    static constexpr bool gui = true;
    static constexpr bool network = false;
};

using Dispatcher = DispatcherT< TimerPump
                                , Traits::gui ? GuiPump : null     <--- need help here
                                , Traits::network ? NetworkPump : null
>;

Is there a neat way to determine arguments passed to a template taking variadic arguments?

>Solution :

Basically, you’d like optional list append. To do that, you first need list append:

template<typename... Ts>
struct list {
    template<typename T>
    using append = list<Ts..., T>;

    template<bool b, typename T>
    using appendIf = std::conditional_t<b, list<Ts..., T>, list<Ts...>>;

    template<template<class...> LT>
    using applyTo = LT<Ts...>;
};

Then you might start with list<> (or whatever types you surely have), then, at each step, use ::appendIf<condition, type> and end with applyTo<DispatcherT>.

using Dispatcher = 
    list<TimerPump>
        ::appendIf<Traits::gui, GuiPump>
        ::appendIf<Traits::network, NetworkPump>
        ::applyTo<DispatcherT>;

Leave a ReplyCancel reply