Я пытаюсь по существу определить класс шаблона, который представляет аппаратное периферийное устройство, у которого есть некоторые переназначаемые выводы. Поскольку сопоставление определяется во время компиляции (или собственно аппаратной схемы c), я хотел бы перенести эти определения через параметры шаблона. Тем не менее, поскольку каждый из выводов может быть отображен независимо от других, набор возможных типов является в основном декартовым произведением отдельных отображений, и я не уверен, что это можно заставить работать. Теперь у меня есть:
enum class SPI1_NSS {
PA4,
PA15
};
enum class SPI1_SCK {
PA5,
PB3
};
template<SPI1_NSS nss_enum, SPI1_SCK sck_enum>
struct SPI_1 {
//...other stuff
struct nss;
struct sck;
};
template<SPI1_SCK sck>
struct SPI_1<SPI1_NSS::PA4, sck>::nss {
using pin = GPIOs::A::pin<4>;
};
template<SPI1_SCK sck>
struct SPI_1<SPI1_NSS::PA15, sck>::nss {
using pin = GPIOs::A::pin<15>;
};
template<SPI1_NSS nss>
struct SPI_1<nss, SPI1_SCK::PA5>::sck {
using pin = GPIOs::A::pin<5>;
};
template<SPI1_NSS nss>
struct SPI_1<nss, SPI1_SCK::PB3>::sck {
using pin = GPIOs::B::pin<3>;
};
Это не с error: invalid class name in declaration of 'class HAL::SPI_1<HAL::SPI1_NSS::PA4, sckp>::nss'
и подобными ошибками для остальных. Это работает, если я удаляю один из двух параметров шаблона.
То, что я ожидал бы получить, это то, что, например, учитывая
using spi = SPI_1<SPI1_NSS::PA4, SPI1_SCK::PB3>;
тип spi::nss::pin
будет GPIOs::A::pin<4>
и spi::sck::pin
будет GPIOs::B::pin<3>
. Возможна ли эта разновидность «декартовой специализации»?
Я понимаю, что могу просто использовать шаблоны для типов GPIO напрямую, и это немного переоценивается. Однако преимущество, которое я получил бы от этого, состоит в том, что enum предоставляет и гарантирует только допустимые варианты выбора для выводов, поэтому он обеспечивает более четкий интерфейс.