使用 static_assert 确保模板参数*最多*只使用一次

Use static_assert to ensure template parameter is only used *at most* once

是否可以确保某个模板参数(或模板参数的组合)最多使用一次?是否可以跟踪它的使用次数,并在多次使用时抛出 static_assert 错误?

举个例子 - 假设我想创建一个静态的、基于模板的 GPIO class:

template<uint8_t Port, uint8_t Pin> class Gpio {};

一个人可以将他们的整个棋盘布置在一个棋盘中 class:

struct Board {
  Gpio<1, 1> myInputPin;
  Gpio<1, 2> myOutputPin;

  Gpio<2, 0> ledR;
  Gpio<2, 1> ledG;
  Gpio<2, 2> ledB;
};

对于任何给定的 port/pin 组合,只有 单个 GPIO 模板为该端口和引脚实例化才有意义。如果有人为相同的 port/pin 组合创建了两个不同的 GPIO 实例,则可能表示存在冲突,我想在编译期间捕获此错误。

这可能吗?

你可以用一个宏来解决这个问题:

#define GPIO(Port, Pin) \
    friend void _gpio_ ## Port ## _ ## Pin(){} \
    Gpio<Port, Pin>

那么如果你使用GPIO(2, 2)两次,编译器会这样说:

error: redefinition of '_gpio_2_2'
  GPIO(2, 2) ledX;
  ^

<source>:14:3: note: previous definition is here
  GPIO(2, 2) ledB;
  ^

演示:https://godbolt.org/z/ronV0u