How to partial specialise a non-argument template, but also have variable templates for arguments

Advertisements

I have a manager class, allows the user to create components via a public interface. The use can specify the component type, and pass in the construction arguments to the manager class, which will create the component object.

However, I am trying to restrict the user from creating certain component type, so their specialisations are private. But because the component type is not a function argument, I can’t figure out how to specialise it.

I am getting the error (Edit: I updated the error since the error in the MRE is different from what it was originally when I posted this question.)

template-id ‘add_component’ in declaration of primary template

#include <utility>

struct A {
    A(float x) {}
};

struct B {
    B(int x) {}
};

class Manager {
public:
    // Allow users to add components via a public interface.
    template<typename T, typename... Args>
    T* add_component(Args&&... _args) {
        return new T(std::forward<Args>(_args)...);
    }

private:
    // But there are certain components that should only be added by the manager.
    template<typename... Args>
    B* add_component<B>(Args&&... _args) {
        return new B(std::forward<Args>(_args)...);
    }
};

int main() {
    Manager m;
    m.add_component<A>(5.0f); // OK
    m.add_component<B>(42); // Not OK
    return 0;
}

>Solution :

The simplest option would be to just use constexpr if as shown below:

class Manager {
public:
    
    template<typename T, typename... Args>
    T* add_component(Args&&... _args) {
        if constexpr(std::is_same_v<T, B>){
            return new B(std::forward<Args>(_args)...);
              
        }
        else 
        {
           return new T(std::forward<Args>(_args)...);
        }
        
    }

private:
    
};

Working demo

Leave a ReplyCancel reply