【问题标题】:Use static_assert to ensure template parameter is only used *at most* once使用 static_assert 确保模板参数只使用*最多*一次
【发布时间】:2019-05-21 11:41:11
【问题描述】:

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

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

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

一个人可以在一个 Board 类中布置整个电路板:

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

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

对于任何给定的端口/引脚组合,只有为该端口和引脚实例化一个单个 GPIO 模板才有意义。如果有人为同一个端口/引脚组合创建了两个不同的 GPIO 实例,这可能表示冲突,我想在编译过程中发现这个错误。

这可能吗?

【问题讨论】:

  • 那么你有一个类,比如Gpio&lt;1, 2&gt;,想保证这个类只有一个对象存在?听起来您想使用单例反模式。

标签: c++ c++11 templates static-assert


【解决方案1】:

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

#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

【讨论】:

  • 这只会防止在同一范围内多次实例化该类。如果您将Gpio&lt;X, Y&gt; 对象分布在多个类/函数中,您仍然可以创建任意数量的对象。
  • @pschill:公平点,我已经更新了我的答案以防止这种情况发生。
猜你喜欢
  • 2023-03-24
  • 1970-01-01
  • 2021-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多