jeudi 19 avril 2018

Change class API depending on template parameter at class creation

I was looking to create a class that under specific template instantiation would expose a different API. It has common functions, but a few should be disabled in the case that the user will use a specific instantiation of the class. Something like this:

VarApi<T1> v1;
v1.funcA1();
// v1.funcA2(); // ERROR
v1.funcA1_2();

VarApi<T2> v2;
// v2.funcA1(); // ERROR
v2.funcA2();
v1.funcA1_2();

I found that you could achieve this with SFINAE and std::enable_if like this:

enum Type { T1, T2, T3 };

template <Type TType> struct VarApi {
    template <Type T = TType,
        typename = typename std::enable_if<T == T1>::type>
    void funcA1()
    { }

    template <Type T = TType,
        typename = typename std::enable_if<T == T2>::type >
    void funcA2()
    { }

    template <Type T = TType,
        typename = typename std::enable_if<T == T1 || T == T2>::type >
        void funcA1_2()
    { }
}; 

This works and achieves the functionality above. The problem is that the user can still override this with:

VarApi<T2> v2;
v2.funcA1<T1>(); // NOT ERROR

Is there a way to prevent this case?

Aucun commentaire:

Enregistrer un commentaire