Search code examples
c++templatesrecursionvariadic-templates

'Could not deduce template argument for 'T'' when trying to parse variadic template


I'm trying to pass in a list of struct types into another class, which will take each custom class and add sort of put the struct type into a wrapper and insert that into a tuple. I'm new to templates in general, and can't figure out why the code wont compile.

The template-parser-wrapper thing

namespace engine
{
    template<class T>
    struct component_manager
    {
        int component_id;

        std::vector<T> components;

        component_manager() : component_id(id_counter) { id_counter++; }
    };

    template<class... Ts>
    class ecs_manager
    {
    public:
        std::tuple<> components;
        
        template<class... Ts>
        ecs_manager()
        {
            constructor_helper<Ts...>();
        }

        template<class T, class... Ts>
        void constructor_helper()
        {
            components = std::tuple_cat(components, component_manager<T>());
            constructor_helper<Ts...>();
        }

        template<class T>
        void constructor_helper() {}
    };
}

The structs

struct transform
{
    engine::vector3 position;
    engine::vector3 rotation;
    engine::vector3 scale;
};

struct motion
{
    engine::vector3 velocity;
};

struct mesh
{
    int id;
};

Creating the template-parser-wrapper-thing engine::ecs_manager<transform, motion, mesh> ecs;

When compiling, I get these: Could not deduce template argument for 'T' No matching overloaded function found


Solution

  • Not sure... but I suppose you're looking for

    template <typename ... Ts>
    class ecs_manager
     {
       public:
          std::tuple<component_manager<Ts>...> components;
        
          ecs_manager () 
              : components{ component_manager<Ts>{} ... }
           { }
     };
    

    Anyway... C++ is a strongly typed language.

    So you can't define an empty tuple

    std::tuple<> components;
    

    and recursively increment it

    components = std::tuple_cat(components, component_manager<T>());
    

    You have to define components as you want and you can't change it's type run-time