Home > Net >  in C , how to create specialization methods deriving from a template base class
in C , how to create specialization methods deriving from a template base class

Time:11-25

i have a template base class with a template method Foo and a concept defining an enum class. i would like to create a deriving class that would create specializations of the method Foo for specific enum class values, like this:

template<typename T>
concept EnumClass = is_scoped_enum<T>::value; // implementation as seen https://en.cppreference.com/w/cpp/types/is_scoped_enum 


template <EnumClass ECA, EnumClass ECB>
class Bar
{
    template<ECA ECAval, ECB ECBval>
    void Foo();
};

enum class A{a};
enum class B{b};

class Deriving : public Bar<A, B>
{};

template<>
void Deriving::Foo<A::a, B::b>() {/* impl... */}

however the following will not compile stating that template-id 'Foo<A::a, B::b> for 'void Deriving::Foo()' does not match any template declaration. can it be modified to work?

CodePudding user response:

Why not do it like this?

#include <type_traits>

//template<typename T>
//concept EnumClass = is_scoped_enum<T>::value; // implementation as seen https://en.cppreference.com/w/cpp/types/is_scoped_enum 

template<typename T>
concept EnumClass = std::is_enum_v<T>; // for testing locally

enum class A { a };
enum class B { b };


template <EnumClass ECA, EnumClass ECB>
class Bar
{
public:
    template<ECA ECAval, ECB ECBval>
    void Foo() {}
};

class Deriving : 
    public Bar<A, B>
{
public:
    void Foo() 
    {
        // you can reuse "base implementation" here if needed
        Bar<A, B>::Foo<A::a, B::b>();
        /* impl... */ 
    }
};


int main()
{
}

CodePudding user response:

Instead of specialization, I suggest overload with tag dispatching:

template <EnumClass ECA, EnumClass ECB, ECA ECAval, ECB ECBval>
void FooImpl(std::integral_constant<ECA, ECAval>,
             std::integral_constant<ECB, ECBval>)
{
    // generic implementation
}

template <EnumClass ECA, EnumClass ECB>
class Bar
{
    template<ECA ECAval, ECB ECBval>
    void Foo()
    {
       FooImpl(std::integral_constant<ECA, ECAval>{},
               std::integral_constant<ECB, ECBval>{});
    }
};

enum class A{a};
enum class B{b};

FooImpl(std::integral_constant<A, A::a>, std::integral_constant<B, B::b>)
{
    // Your specialization
}

No uses of Derived...

  • Related