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

时间:2015-12-28 05:26:45

标签: c++ templates generic-programming

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

我使用带有'int'参数

的模板类来定义Pins
template<const int pin>
struct Pin {
    Pin() { mode(pin, 0); }
};

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

我可以创建模板类来使用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的类中使用模板。这说明了我的想法,显示了可能的方法,但显然不起作用。

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

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

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

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 ++特别是模板的理解。我知道还有其他方法。

1 个答案:

答案 0 :(得分:1)

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

但Pin的整个家族是否在不知道T的情况下有些有意义?这可以使用非模板的基类来处理。基类的想法特别方便,因为它可以包含了解T的虚函数。这使您可以根据需要在编译时和运行时多态之间切换。采取相同的语法#34; Generics&#34;如Java和.NET所示。

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

在你的情况下,pin是一个非类型参数,这是泛型甚至不做的事情。但它可能根本不会真正影响类型:成员的变化取决于pin?这可能是一个数组绑定,或者是用于提供编译时知识和优化的编译时常量,或者仅用于使类型不同。

所有这些案例都可以在运行时处理。如果它的唯一目的是使类型不同(例如,让编译器检查您将时间值和距离值传递给正确的参数)那么真正的内容是 all 在一个基础中忽略了独特性的课程。

如果它是一个数组绑定或其他类型的差异,可以在运行时进行管理,那么基类或适配器/代理可以在运行时进行。更一般地说,一个不会影响类布局的编译时常量可以在运行时以相同的效果知道,只需要更少的优化。

从您的示例中,使引脚成为构造函数参数是明智的,类可以以正常方式使用运行时配置实现。为什么它是模板?据推测,对于编译时检查,将单独的事物分开。这并不会导致它们以不同的方式工作,因此您希望编译时部分是可选的。因此,这是一个基类可以解决问题的情况:

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

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

现在您可以编写采用AnyPin的函数,或编写采用Pin&lt; 5&gt;的函数。并获得编译时检查。

那么pin在类的布局和功能方面做了什么呢?是否有任何使得将其作为运行时构造函数值实现的不可接受的事情?

您要求我们不要询问您尝试做什么,但我必须说模板具有某些功能和优点,并且必须有一些理由将其作为模板。简单地说以语言为中心的术语,我是否因为上述分析而错过了什么?如果我的摘要没有涵盖它,你能否给出C ++编程的理由,希望它成为一个模板?这可能就是为什么到目前为止你没有得到任何答案。