Search code examples
c++templatestemplate-meta-programming

Automate repeated code for various types?


Is there is any way by which I can automate this

DeserializeComponent<IDComponent>(json, e);
DeserializeComponent<NameComponent>(json, e);
DeserializeComponent<PointLightComponent>(json, e);
// ...

As you can see here, the same code is executed for different types, but in C++ you can't store types in a std::vector as far as my knowledge goes. Is there is any way by which I can automate this? Like looping over the components that I add to a vector in application startup? Also, I want to avoid RTTI.


Solution

  • Types can't be stored in variables. Types are only for the compiler. Even RTTI doesn't store types in variables, but rather "names" of types.

    I think you just want to make the code shorter by not having to type DeserializeComponent<>(json, e); over and over. Well, you can do that with parameter pack expansion.

    template<typename... Components>
    void DeserializeComponents(json_t& json, e_t& e)
    {
        (DeserializeComponent<Components>(json, e), ...);
    }
    
    // ...
    
    DeserializeComponents<IDComponent, NameComponent, PointLightComponent>(json, e);
    

    The magic is in typename... Components - which says Components is not just one type argument but a list of type arguments - and (DeserializeComponent<Components>(json, e), ...); which says to copy-paste the function call for each Components argument, and join them together with the comma operator ,

    When the compiler expands the template, the expanded template looks like this:

    void DeserializeComponents<IDComponent, NameComponent, PointLightComponent>(json_t& json, e_t& e)
    {
        (
         DeserializeComponent<IDComponent>(json, e),
         DeserializeComponent<NameComponent>(json, e),
         DeserializeComponent<PointLightComponent>(json, e)
        );
    }