Specialization of a template class using enable_if

93 views Asked by At

I am trying to partially specialize a template class which belongs to an external library. The external code is basically as follows.

template <typename T>
struct MyStruct;

I would like the specializations of enum types to be the same. In C++20, I can achieve this by using concepts.

template <typename T>
concept enum_concept = std::is_enum_v<T>;

template <enum_concept Enum>
struct MyStruct<Enum> {
    // ...
};

However, I am having difficulties doing the same in C++17. So far, I tried using enable_if as a non-type parameter.

template <typename Enum, std::enable_if_t<std::is_enum_v<Enum>, bool> = true>
struct MyStruct<Enum> {
    // ...
};

But I get the following error messages.

error C2756: 'unnamed-parameter': default template arguments not allowed on a partial specialization
error C2753: 'MyStruct<Enum>': partial specialization cannot match argument list for primary template
error C2764: 'unnamed parameter': template parameter not used or deducible in partial specialization 'MyStruct<Enum>'

If the primary template had another template argument, I could write the following code.

template <typename T, typename = void>
struct MyStruct;

template <typename Enum>
struct MyStruct<Enum, std::enable_if_t<std::is_enum_v<Enum>>> {
    // ...
};

Is it possible to partially specialize the template class without modifying the primary template in C++17?

1

There are 1 answers

4
Pepijn Kramer On

You could just inherit MyStruct from the external struct and do this :

#include <type_traits>
#include <iostream>

template<typename  T>
struct TheirStruct
{
    int x{42};
};

template <typename T, typename = void>
struct MyStruct;

template <typename Enum>
struct MyStruct<Enum, std::enable_if_t<std::is_enum_v<Enum>>> :
    public TheirStruct<Enum>
{
};

enum class MyEnum
{
    One = 1,
    Two = 2
};

int main()
{
    MyStruct<MyEnum> mystruct;
    //MyStruct<int> mystruct2; <== will not compile
    std::cout << mystruct.x;
}