Как переслать объявление класса enum как внутреннего класса шаблонного класса? - PullRequest
1 голос
/ 09 января 2020

Я абстрагирую таблицу векторов прерываний на нескольких микроконтроллерах. Я использую шаблонные классы в форме (InterruptVectorTable.hpp (определение, включенное в реализацию))

template<class Device, class ResultType>
InterruptVectorTable
{
    enum class IRQType : ResultType;

}

Device - это своего рода фиктивный класс, который используется для специализации шаблона.

class DeviceAtMega328p 
{
      public:
        static const int s_NumInterruptVectors = {26};
};

(Здесь я все еще думаю о том, передавать ли 26 в качестве параметра шаблона или в этой форме.)

Поскольку у каждого микроконтроллера есть свои собственные типы и значения прерываний, которые следует проверить во время компиляции (из-за класса enum) я хотел бы также специализировать указанные прерывания c в этой форме (InterruptVectorTable.hpp (Реализация):

template<>
InterruptVectorTable< DeviceAtMega328p, uint8_t>
{
    enum class IRQType : ResultType
    {
        //RESET_IRQn = 0,               // Not available.
        INT0_IRQn = 1,
        INT1_IRQn = 2,
        PCINT0_IRQn = 3,
        PCINT1_IRQn = 4,
        PCINT2_IRQn = 5,
        WDT_IRQn = 6, 
        // .....
    };
}

Этот подход, кажется, не работает как ожидается (в настоящее время слишком много ошибок, чтобы указать, который явно указывает на эту часть).

1 Ответ

3 голосов
/ 09 января 2020

Во-первых, это не то, как вы вводите новый класс шаблона:

// Wrong!
template<>
InterruptVectorTable<class Device, class ResultType>
{
    // ...
}

Правильный путь:

template<class Device, class ResultType>
class InterruptVectorTable
{
    // ...
};

Во-вторых, вы не можете «объявить вперед» что-то в шаблоне, которое должны определить специализации шаблона. Специализация ничего не знает и не имеет ничего общего с «базовым регистром».

Ваш код будет работать, если вы просто выполните:

template<>
class InterruptVectorTable<DeviceAtMega328p, uint8_t>
{
    enum class IRQType : uint8_t
    {
        //RESET_IRQn = 0,               // Not available.
        INT0_IRQn = 1,
        INT1_IRQn = 2,
        PCINT0_IRQn = 3,
        PCINT1_IRQn = 4,
        PCINT2_IRQn = 5,
        WDT_IRQn = 6, 
        //...........
    };
};

Пользователи InterruptVectorTable просто предположят, что каждая специализация определяет enum class IRQType. Не существует прямого способа заставить специализацию сделать это. Та же история для требования IRQType, имеющего ResultType в качестве базового типа.

...