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

标签 c++ templates generic-programming

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

我使用带有“int”参数的模板类定义 Pin

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

最佳答案

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

但是 Pin 的整个家族是否以某种方式相关,以至于在不知道 T 的情况下某些事情是有意义的?这可以使用非模板的基类来处理。基类的想法特别方便,因为它可以包含确实知道 T 的虚函数。这使您可以根据需要在编译时和运行时多态性之间即时切换。在极端情况下,这与 Java 和 .NET 中所见的“泛型”语法相同,成为较弱的想法。

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

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

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

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

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

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

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

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

那么 pin 在布局和功能方面对类做了什么?它是否做了任何让仅将其实现为运行时构造函数值变得 Not Acceptable 事情?

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

关于c++ - 使用模板类型将参数传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34488091/

相关文章:

c++ - 在 C++ 控制台中更改特定字符的颜色

c++ - 将非指针分配给指针? (在 C++ 中子类化指针类型?)

c++ - 作为仿函数模板的模板参数

swift - 无法将类型 'GenericTableViewController<T, U>' 的值分配给类型 'GenericTableViewController<GenericTableViewCell<_>, _>'

mongodb - 如何编写通用 ASP.NET Core ApiController 从客户端执行 MongoDB CRUD 操作?

c++ - Haxe/openfl 文本字段内存泄漏

c++ - Windows 8 sfml 和代码块的编译器错误

c++ - 不完整类型的无效使用 - 为什么在这种情况下没有错误?

c# - 如何将对象转换为类型?

使用 future 、 promise 、分离线程时出现 C++ 错误 C2893、C2780、C2672