1

I'm abstracting the interrupt vector table on multiple microcontrollers. I am using template classes in the form of (InterruptVectorTable.hpp(definition, included in implementation))

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

}

Device is a kind of dummy class that is used to specialize the template.

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

(Here I'm still thinking about whether to pass the 26 as template parameter or in this form.)

As each microcontroller has its own types and values of interrupts, that should be checked at compile time (because of enum class), I'd like to also specialize the specific interrupts in this form(InterruptVectorTable.hpp(Implementation):

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, 
        // .....
    };
}

This approach seems not to work as expected(currently too many errors to specify, which explicitly one specifies this part).

3
  • Please provide a minimal reproducible example, your code as posted doesn't compile due to lack of the original InterruptVectorTable class. You're probably in need of some sort of traits pattern but its difficult to say without more details Commented Jan 9, 2020 at 17:26
  • The Atmega328p (usually found in Arduino UNOs) does not support the C++ standard library, thus only "basic" C++ facilities apply. Commented Jan 9, 2020 at 17:40
  • 2
    You don't need the standard library to implement a traits pattern, its a language feature Commented Jan 9, 2020 at 18:21

1 Answer 1

3

First of all, this is not how you introduce a new template class:

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

Right way:

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

Second, you can't "forward-declare" something in a template that the template specializations will have to define. The specialization knows nothing about and has nothing in common with the "base case".

Your code will work if you just do:

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, 
        //...........
    };
};

Users of InterruptVectorTable will simply assume that each specialization defines an enum class IRQType. There is no direct way to force specializations to do so. Same story for the requirement of IRQType having ResultType as underlying type.

Sign up to request clarification or add additional context in comments.

2 Comments

Well, my problem extends to the InterruptVectorTable base class defining member functions that depend on arguments of type IRQType being passed. auto setCallback(IRQType InterruptIndex, void (*Callback)(void)) -> void;, might maybe pass the IRQType as template parameter?
@JohnBehm Passing IRQType as template parameter could be an option, but it will have to be defined before (as in outside) the specialization for that to work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.