C++ variadic template 'contains no parameter packs' when constexpr if should avoid?

97 Views Asked by At

I am using some c++ 20 features such as the fold operator to gain the size of a variadic template at compile time. I am then using this size in a constexpr if to avoid any usage of the variadic template if there are no templates provided.

However i am still getting the error:


src/engine/inb/component.h:39:68: error: expected primary-expression before '>' token
   39 |                 swallowTemplateExpansion(i_addComponent<_Components>(inheritor)...);
      |                                                                    ^
src/engine/inb/component.h:39:80: error: expansion pattern '((((cosmic::ComponentHolder<_Child>*)this)->cosmic::ComponentHolder<_Child>::i_addComponent < <expression error>) > (inheritor))' contains no parameter packs
   39 |                 swallowTemplateExpansion(i_addComponent<_Components>(inheritor)...);
      |                                                                                ^~~

Which is telling me that the compiler evaluates the else statement anyway? constexpr avoids code like this at compile time so it shouldn't give me this error.

here is the code:


template<typename _Child>
    struct ComponentHolder
    {
    private:
        std::vector<std::shared_ptr<Component<_Child>>> components{};
        int i_addComponent(_Child* inheritor)
        {
            components.push_back(std::make_shared<Component<_Child>>(inheritor));
            return 0;
        }
    public:
        template<typename... _Components>
        constexpr ComponentHolder(_Child* inheritor)
        {
            constexpr auto _Size = (sizeof(_Components) + ...);
            if constexpr (_Size == 0)
            {
                return;
            } 
            else {
                swallowTemplateExpansion(i_addComponent<_Components>(inheritor)...);
            }
        }
    };

And swallowTemplateExpansion is just a blank consumer void function:


template<typename... T>
    void swallowTemplateExpansion(T&&... x)
    {}

Why is my constexpr if still trying to unpack the variadic template when i have told the compiler if its size is 0, don't unpack the variadic template?

thanks in advance for any help!

1

There are 1 best solutions below

0
TBCM On

I solved this by providing the template argument to the i_addComponent function, a very silly mistake.

template<typename _Component>
        int i_addComponent(_Child* inheritor)
        {
            components.push_back(std::make_shared<_Component>(inheritor));
            return 0;
        }