具有非类型模板的结构的 C++ 实例化

C++ Instantiation of a struct which have a non-type template

通常,我们可以通过以下方式创建一个或多个结构实例:

struct
{
  const uint8_t Address;
  struct
  {
    uint8_t GPIO1 : N;
    uint8_t GPIO2 : N;
    uint8_t GPIO3 : N;
    uint8_t GPIO4 : N;
    uint8_t GPIO5 : N;
    uint8_t GPIO6 : N;
    uint8_t GPIO7 : N;
    uint8_t GPIO8 : N;
  } Value;
} Register1, Register2;

不幸的是,当结构有模板时似乎不是这种情况(VSCode 给出语法错误):

template<uint8_t N = 1> struct
{
  const uint8_t Address;
  struct
  {
    uint8_t GPIO1 : N;
    uint8_t GPIO2 : N;
    uint8_t GPIO3 : N;
    uint8_t GPIO4 : N;
    uint8_t GPIO5 : N;
    uint8_t GPIO6 : N;
    uint8_t GPIO7 : N;
    uint8_t GPIO8 : N;
  } Value;
} <1>Register1, <2>Register2;

我想不出不允许这样做的原因。是否有关于为什么不允许这样做的具体答案,或者仅仅是因为标准中未定义此语法?

编辑:

因为它可以被视为一个基于意见的问题,我想知道是否有类似的语法可以工作。

与一般结构的情况不同,规则规定,

“不应该存在没有名称的模板class”

如果你仔细想想,这是有道理的。在匿名结构的定义结束之后,除了对象名称之外应该没有其他内容。所以没有模板参数的余地。

同样,即使可以将模板参数放在匿名模板之后,然后声明 2 个对象

<1>Register1, <2>Register2;

一起,一个接一个,又是一个问题!

使用命名空间可能是您认为有用的替代解决方案。

如果您真的需要匿名,另一种解决方案可能如下所示:

struct{
template<uint8_t N = 1>
struct Reg
{
  const uint8_t Address{};
  struct
  {
    uint8_t GPIO1 : N;
    uint8_t GPIO2 : N;
    uint8_t GPIO3 : N;
    uint8_t GPIO4 : N;
    uint8_t GPIO5 : N;
    uint8_t GPIO6 : N;
    uint8_t GPIO7 : N;
    uint8_t GPIO8 : N;
  } Value;
};
Reg<1> Register1;
Reg<2> Register2;
}Regs;

uint8_t v1 = Regs.Register1.Address;
uint8_t v2 = Regs.Register2.Address;

这和你想的不一样。

此外,如果您只打算使用模板结构几次,那么只为那几次编写等效的匿名结构可能值得:


struct
{
  const uint8_t Address{};
  struct
  {
    uint8_t GPIO1 : 1;
    uint8_t GPIO2 : 1;
    uint8_t GPIO3 : 1;
    uint8_t GPIO4 : 1;
    uint8_t GPIO5 : 1;
    uint8_t GPIO6 : 1;
    uint8_t GPIO7 : 1;
    uint8_t GPIO8 : 1;
  } Value;
}Register1;

struct
{
  const uint8_t Address{};
  struct
  {
    uint8_t GPIO1 : 2;
    uint8_t GPIO2 : 2;
    uint8_t GPIO3 : 2;
    uint8_t GPIO4 : 2;
    uint8_t GPIO5 : 2;
    uint8_t GPIO6 : 2;
    uint8_t GPIO7 : 2;
    uint8_t GPIO8 : 2;
  } Value;
}Register2;

.
.
.