0

I want to create a static method in a class which basically just creates components for me and i want to overload this method for different classes, but i just can't get it to work. This is the best i came up with so far:

    template <typename T, typename... Args>
    static T* _Create(Args&&... args) 
    {
        T* component = new T(std::forward<Args>(args)...);
        return component;
    }

    template <typename T, typename... Args, typename std::enable_if<std::is_same<Camera, T>::value>::type* = nullptr>
    static T* _Create(Args&&... args) 
    {
        T* component = new T(std::forward<Args>(args)...);
        // Do stuff with the component e.g. add it to a list
        return component;
    }

    template <typename T, typename... Args, typename std::enable_if<std::is_base_of<CRenderer, T>::value>::type* = nullptr>
    static T* _Create(Args&&... args) 
    {
        T* component = new T(std::forward<Args>(args)...);
        // Do stuff with the component e.g. add it to a list
        return component;
    }

But of course this doesn't work because the _Create with "Camera" does match the first and second function. Can somebody please push me in the right direction? How can i achieve this?

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
Silvan Hau
  • 85
  • 1
  • 8
  • 1
    Probably unrelated, but worth reading just in case: [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) – user4581301 Mar 06 '18 at 23:48
  • 1
    There is no specialization here, only overloading. You need to disable the first overload when any of the others would be valid. That's going to involve another `enable_if`. – Miles Budnek Mar 06 '18 at 23:52
  • Yea i thought of that too, but if i have several classes who want to use this function, i have to include an enable_if for every overloaded type, otherwise the general function will always match with the other one. That would be so awkward. – Silvan Hau Mar 06 '18 at 23:56
  • Are you using C++17? If so, the separate functions are entirely unnecessary. – Drew Dormann Mar 06 '18 at 23:58
  • No i don't, but i could enable it i guess. I develop with vs17. What do you mean exactly? – Silvan Hau Mar 07 '18 at 00:00

1 Answers1

2

Since you have access to C++17 (and have shown hesitance to add more enable_ifs)...

You may collapse all your functions into one using if constexpr!

template <typename T, typename... Args>
static T* _Create(Args&&... args) 
{
    T* component = new T(std::forward<Args>(args)...);

    if constexpr( std::is_same<Camera, T>::value )
    {
        // Do stuff with the component e.g. add it to a list
    }

    if constexpr( std::is_base_of<CRenderer, T>::value )
    {
        // Do stuff with the component e.g. add it to a list
    }

    return component;
}

This will produce code as efficient as the code you have written.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • Very nice with c++17 being able to eliminate the need for `std::enable_if` as a template parameter by just being able to use `if constexpr(...)` within the body of the function template. I'll have to remember this! – Francis Cugler Mar 07 '18 at 01:43