C++ 部分类模板针对多个参数的特化

标签 c++ templates c++17 partial-specialization

我试图本质上定义一个代表硬件外设的模板类,它有一些可重新映射的引脚。由于映射是在编译(或实际上是硬件原理图绘制)时定义的,我想通过模板参数引入这些定义。然而,由于每个引脚都可以独立于其他引脚进行映射,因此可能的类型集基本上是各个映射的笛卡尔积,我不确定这是否可以工作。我现在拥有的是:

     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 类型上进行模板化,这有点过度设计了。然而,我从中得到的好处是枚举仅提供并保证引脚的有效选择,因此它可以提供更清晰的界面。

最佳答案

如果您的目的是专门化正交性,我会使用不嵌套在 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>;
};

关于C++ 部分类模板针对多个参数的特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60504538/

相关文章:

c++ - 在 visual studio 2010 和 c++ 中使用 OpenGL 绘制带有箭头的轴

c++ - 将 Makefile 转换为 Tiva C 系列的 CMakeLists.txt

c++ - Apple Clang 和 numeric_limits<unsigned __int128>::max() 是 0?

c++ - 当 Type = bool 时,运算符 bool() 与模板 Type() 运算符冲突

C++:你能做一个 lambda 隐式复制捕获加上显式复制捕获吗?

C++ unique_ptr 常量引用

c++ - 公共(public) "using"= decltype(<private>)

c++ - 如何有条件地将函数添加到类模板?

c++ - 在 C++17 中迭代时从 std::set 中删除元素

c++ - 将对象移到unique_ptr