【问题标题】:function Template with explicit type names具有显式类型名称的函数模板
【发布时间】:2013-04-28 02:25:23
【问题描述】:

我一直在阅读一些关于 templates 的网页。

我看到了,templates 是这样使用的:

template <typename T>
T func(T a) {...}

因此,它可以灵活地为不同类型的变量使用相同的代码。 而且,我们可以使用似乎只适用于类的专业化,就像:

template <> class A<int> {....}

但是我没有找到这样的用法:

template<int N, bool isVertical, bool isFirst, bool isLast>
static void filter(int bitDepth, Pel const *src, int srcStride, 
                   short *dst, int dstStride, int width, 
                   int height, short const *coeff);

它是这样称呼的:

filter<N, false, true, true>(bitDepth, src, srcStride, dst, dstStride, width, height, coeff);

在这段代码中,模板被赋予了真实和绝对类型,恕我直言,我们可以在过滤器的参数列表中添加另外四个参数而不是使用模板。

那么,为什么要这样使用模板呢?

【问题讨论】:

  • 我相信这是为了确保它们是编译时值(即常量表达式)。

标签: c++ function templates


【解决方案1】:

templates 不是函数。 templates 是函数工厂,参数决定了生成哪个函数。

template 函数也有基于参数的类型推导,但这只是确定 template 函数工厂生成的函数)。

所以这个:

template<int N, bool isVertical, bool isFirst, bool isLast>
static void filter(int bitDepth, Pel const *src, int srcStride, 
               short *dst, int dstStride, int width, 
               int height, short const *coeff);

没有定义一个filter 函数,而是定义了一整套这样的函数。

filter 之后的&lt;&gt; 中的参数是传递给template 函数工厂以确定实际生成的函数的参数。

当这些函数由工厂生成时(在编译时),传入template 函数工厂的值是已知的。因此围绕这些常量进行优化非常容易。

确实,内联和 as-if 规则可以让编译器接受文字参数,推断给定参数是编译时常量,并在包含该常量的情况下编译函数——但这种技术既脆弱又脆弱有限。

带有template 工厂生产的函数,它是一个实际函数。因此,您可以存储指向它的指针并将其作为无状态函数传递。

举个具体的例子,假设你想处理一张图片。现在处理图像的实用方法是使用一些数据建立一个基于扫描线的函数,然后迭代图像的扫描线,将每一条扫描线传递给基于扫描线的函数。

另一方面,许多图像变换是逐像素变换。在每个图像转换函数中对这些像素编写所有优化循环会导致大量复制粘贴代码。但是您不能将指向基于像素的操作的指针传递给扫描线处理函数——与典型的每像素操作相比,取消引用指针的开销要高得多。

因此,您创建了一个 template 函数工厂,该工厂在编译时采用每像素函数,并将其包装在对像素代码的迭代中。开销就消失了。

更重要的是,你可能会传入另一个template 函数工厂(通过template class)而不是像素操作,所以如果你正在做SSE 类型的组装,你可以执行设置之类的操作,多少像素每像素操作应该一次处理,等等。

结果可能是一堆用ifs 编写的代码,看似充满了分支和条件,但当您将所有参数作为模板传入时,实际上编译为几乎完全平坦且无分支的扫描线操作论据。

简而言之,templates 有助于解决传统上通过代码生成解决的问题——无论是宏还是第三方工具。它们足够强大和方便,人们可以在您以前从未烦恼过的情况下使用它们来生成代码,例如为每种用户类型生成自定义容器、自定义搜索算法、散列算法、迭代、for 循环以及无数其他太傻了。

templates 可以做的所有事情都可以在没有它们的情况下完成,但这并不奇怪:当心图灵 tar 坑,那里一切都是等价的,但没有什么是容易导入的。 templates 使某种代码生成简单

【讨论】:

  • 一个相当全面的答案!我会比“模板帮助解决传统上通过代码生成解决的问题”更进一步,并说“模板是代码生成,内置在语言中”。因此“模板元编程”。 +1。
  • @JohnZwinck 传统的代码生成实际上会生成文本,然后像您输入它一样编译:templates 不要那样做(如果你认为会导致许多误解),所以我想区分template类型和函数工厂和传统的“代码生成”。
  • 很公平。具有讽刺意味的是,一些外部代码生成器比 C++ 模板产生更好的诊断——即使诊断是由编译器发出的,它本身不知道代码生成步骤!当然,对于使用最新编译器的人来说,最近情况有所好转,但仍然如此。
猜你喜欢
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-25
  • 1970-01-01
相关资源
最近更新 更多