使用模板类型将参数传递给函数

Passing Arguments to Function using Template Types

我正在将 IMO 推向 C++ 模板编程的极限。该系统是一个 Arduino,但我的尝试适用于任何微控制器系统。

我使用带有 'int' 参数的模板 class 定义 Pin 图

template<const int pin>
struct Pin {
    Pin() { mode(pin, 0); }
};

template<const int pin>
class PinOut : public Pin<pin> {};  

我可以创建模板 classes 来使用 PinOut,例如:

template<typename F>
class M {
public:
    M() { }
    F mF;
};

M<PinOut<1>> m1;

template<int F>
class N {
public:
    N() { }
    Pin<F> mF;
};

N<1> n1;

但我不想在使用 PinOut 的 classes 中使用模板。这说明了我的想法,显示了可能的方法,但显然行不通。

class R {
public:
    R(const int i) {
    }
PinOut<i> mF;  // create template instance here
};

R r1(1);  // what I'd like to able to do

我认识到问题是在 class R 中创建一个类型。

另一种可能性是实例化 PinOut 变量并将其传入,但再次在 class 中传递和创建类型是一个问题。像这样:

class S {
public:
    S(PinOut<int>& p) { } // how to pass the type and instance
    PinOut<p>& mF;   // and use it here
};

PinOut<1> pp;
S s1(pp);

抱歉,如果这听起来很突兀,但请不要问我为什么或我想做什么。这是一个实验,我正在推动我对 C++ 尤其是模板的理解。我知道还有其他方法。

是的,任何采用该类型的函数本身都必须是模板。

但是 Pin 的整个家族是否以某种方式相关,某些事情在不知道 T 的情况下有意义?这可以用 non-template 的基数 class 来处理。基本 class 思想特别方便,因为它可以包含 知道 的有关 T 的虚函数。这使您可以在 compile-time 和 run-time 多态性之间切换根据需要在飞行中。在极端情况下,与在 Java 和 .NET.

中看到的 "Generics" 语法相同,这成为较弱的想法

更一般地说,这是一个称为类型擦除的概念。您可以搜索该术语以了解更多信息。它被设计到库中,以保持通用代码的通用性,并防止通过多个实例无故增加同一段落。

在你的例子中,pin 是一个 non-type 参数,这是泛型甚至不做的事情。但它可能 真的 根本不会影响类型:成员会根据 pin 发生什么变化?这可能是一个数组绑定,或者是一个 compile-time 常量,用于提供 compile-time 知识和优化,或者只是为了使类型不同。

所有这些情况也都可以在 run-time 处理。如果它的唯一目的是使类型不同(例如,让编译器检查您是否将时间值和距离值传递给正确的参数),那么真正的胆量是 all in a base class 省略了显着性。

如果 可以 在 run-time 处管理的数组绑定或其他类型差异,则基数 class 或 adapter/proxy 可以做到 run-time。更一般地说,不影响 class 布局的 compile-time 常量可以在 run-time 处知道,具有相同的效果,只是优化较少。

从你的例子来看,将 pin 设为构造函数参数是明智的,class 可以 以 run-time 的正常方式实现配置。为什么是模板?大概是为了 compile-time 检查以将不同的东西分开。这不会导致它们以不同的方式工作,因此您希望 compile-time 部分是可选的。所以,在这种情况下,基数 class 可以解决问题:

class AnyPin
{
public:
   AnyPin (int pin);  // run-time configuration
};

template <int pin>
class Pin : public AnyPin { ⋯ };

现在您可以编写采用 AnyPin 的函数,或编写采用 Pin<5> 并进行 compile-time 检查的函数。

那么 pin 在布局和功能方面对 class 做了什么?它是否做了任何让仅将其实现为 run-time 构造函数值不可接受的事情?

你问我们不问你要做什么,但我必须说,模板有一定的特点和好处,做模板肯定是有原因的。简单地说 language-centric ,上面的分析我是不是漏掉了什么?如果我的摘要没有涵盖它,您能否给出一个 C++ 编程理由来希望它成为一个模板?这可能就是您迄今为止没有得到任何答案的原因。