Search code examples
c++templatespartial-specializationexplicit-specialization

Can I create a partial template specialization of of a class template matching enumeration types?


I have a function template powered by a set of class template explicit specializations giving syntax like

abc.GetAs<DesiredType>("Name");

(where GetAs<t> is something like:

template<typename T>
T GetAs(wchar_t const* propName) const
{
    typedef Converter<T> Converter;
    auto thing = Get(propName);
    return Converter::Convert(thing);
}

)

I would like to have a specialization for DesiredType when that type is an enumeration, so that the returned type matches the underlying type of the enumeration (or enum class).

Is that possible or do clients just have to specify the underlying type themselves?


I'm trying to allow code like this:

enum class Example
{
    One,
    Two
}

int main()
{
    foo_ipc_class ic(L"/// Construct me");
    // Today, calls the primary template rather than an explicit
    // specialization for an integral type.
    Example ex = ic.GetAs<Example>(L"Property Name");
}

Solution

  • As it's impossible to partially specialise function templates, you'll have to change your implementation to use the "delegate-to-class" trick:

    #include <type_traits>
    
    // Class to delegate to
    template <typename T, bool isEnum = std::is_enum<T>::value>
    struct GetAs_Class {
      typedef your_return_type ReturnType;
      static ReturnType GetAs(your_parameters) { your_code; }
    };
    
    // Partial specialisation    
    template <typename T>
    struct GetAs_Class<T, true> {
      typedef specialisation_return_type ReturnType;
      static ReturnType GetAs(your_parameters) { specialisation_code; }
    };
    
    
    // Your function now delegates to the class
    template <typename T>
    typename GetAs_Class<T>::ReturnType GetAs(your_parameters) {
      return GetAs_Class<T>::GetAs(your_arguments);
    }