C++ C++;多参数上的部分类模板专门化
我试图从本质上定义一个表示硬件外围设备的模板类,它有一些可重新映射的管脚。由于映射是在编译时(实际上是硬件原理图绘制时)定义的,所以我想通过模板参数引入这些定义。然而,由于每个管脚都可以独立于其他管脚进行映射,因此可能的类型集基本上是各个映射的笛卡尔积,我不确定这是否可以实现。我现在得到的是:C++ C++;多参数上的部分类模板专门化,c++,templates,c++17,partial-specialization,C++,Templates,C++17,Partial Specialization,我试图从本质上定义一个表示硬件外围设备的模板类,它有一些可重新映射的管脚。由于映射是在编译时(实际上是硬件原理图绘制时)定义的,所以我想通过模板参数引入这些定义。然而,由于每个管脚都可以独立于其他管脚进行映射,因此可能的类型集基本上是各个映射的笛卡尔积,我不确定这是否可以实现。我现在得到的是: enum class SPI1_NSS { PA4, PA15 }; enum class SPI1_SCK { PA5,
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>;
};
enum类SPI1\u NSS{
PA4,
PA15
};
枚举类SPI1\U SCK{
PA5,
PB3
};
模板
结构SPI_1{
//…其他东西
结构nss;
结构sck;
};
模板
结构SPI_1::nss{
使用pin=GPIOs::A::pin;
};
模板
结构SPI_1::nss{
使用pin=GPIOs::A::pin;
};
模板
结构SPI_1::sck{
使用pin=GPIOs::A::pin;
};
模板
结构SPI_1::sck{
使用pin=GPIOs::B::pin;
};
此操作失败,出现错误:“class HAL::SPI_1::nss”声明中的类名无效以及其他类似错误。如果我删除两个模板参数中的一个,它就会工作
我期望得到的是,例如
using spi = SPI_1<SPI1_NSS::PA4, SPI1_SCK::PB3>;
使用spi=spi_1;
类型spi::nss::pin
将是GPIOs::A::pin
,spi::sck::pin
将是GPIOs::B::pin
。这种“笛卡尔专门化”是否可能
我确实意识到我可以直接在GPIO类型上创建模板,这有点过度设计了。然而,我从中得到的好处是,枚举只提供并保证管脚的有效选择,因此它提供了更清晰的接口。如果您想专门化正交性,我会使用不同的元函数,这些元函数不嵌套在SPI_1
namespace detail {
template<SPI1_NSS>
stuct nss;
template<>
struct nss<PA4> {
using pin = GPIOs::A::pin<4>;
};
template<>
struct nss<PA15> {
using pin = GPIOs::A::pin<15>;
};
// Same for sck
}
template<SPI1_NSS nss_enum, SPI1_SCK sck_enum>
struct SPI_1 {
//...other stuff
using nss = detail::nss<nss_enum>;
using sck = detail::sck<sck_enum>;
};
名称空间详细信息{
模板
stuct-nss;
模板
结构nss{
使用pin=GPIOs::A::pin;
};
模板
结构nss{
使用pin=GPIOs::A::pin;
};
//同样适用于sck
}
模板
结构SPI_1{
//…其他东西
使用nss=详细信息::nss;
使用sck=detail::sck;
};
当然,由于我能够在单参数情况下使用嵌套版本,所以我不知何故被困在了嵌套版本上,而且可以说它更“优雅”。我会按惯例等待24小时,然后接受你的答复。