Search code examples
c++templatesstatic-methods

C++ static evaluation of templated argument


Function that I can't seem to get to work:

void Add(const Event &event, T callback) noexcept
    {
        if constexpr (event == Event::Type1)
        {
            m_type1callbacks.push_back(callback);
        }
        else if constexpr (event == Event::Type2)
        {
            m_type2Callbacks.push_back(callback);
        }
        else if constexpr (event == Event::Type3)
        {
            m_type3Callbacks.push_back(callback);
        }
        else if constexpr (event == Event::Type4)
        {
            m_type4LeaveCallbacks.push_back(callback);
        }
    }

Functionality: Depending on event I want to add callback to a container of callback-functions

Note: Each container is templated on different templated versions of std::function<>

What I want to achive: The expression to be evaluated at compile time and thus generate function bodies depending on event. So, if m_type1Callbacks is templated on std::function, the function:

Add(Event::Type1, [](int foo){std::cout << foo << std::endl;}));

should be added to m_type1Callbacks

My problem: When I try the code above I get the error:

'event' is not a constant expression

What I want help with: Is my way of solving this problem wrong fundmentally? How should I improve and solve this problem?

Thanks in advance!


Solution

  • If you make event a template parameter to your function, you will be able to use it in a constexpr context:

    template <Event event>
    void Add(T callback) noexcept
    {
        if constexpr (event == Event::Type1)
        {
            m_type1callbacks.push_back(callback);
        }
        else if constexpr (event == Event::Type2)
        {
            m_type2Callbacks.push_back(callback);
        }
        else if constexpr (event == Event::Type3)
        {
            m_type3Callbacks.push_back(callback);
        }
        else if constexpr (event == Event::Type4)
        {
            m_type4LeaveCallbacks.push_back(callback);
        }
    }