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
...