将正常功能更改为模板会产生正/负差异吗?

问题描述

| 我有一个包装函数(模板化))0ѭ,核心功能functionality1ѭ。
namespace N
{
  A* Inner (void *p,int value,const int ID);

  template<typename T>
  A* Outer (T *p,const int ID)  // ID is a compile time constant
  {
    return Inner (p,p->value,ID);
  }
}
用法
A *px = Outer(new X(3),12345);
A *py = Outer(new Y(4),987);
我设法通过一个编译时常量作为ID。因此,我正在考虑将“ 0”原型更改为
template<int ID,typename T>
A* Outer (T *p)
{
  return Inner (p,ID);
}
用作
A *pz = Outer<333>(new Z(5));
想知道,新方法是否会对代码/性能级别产生影响?会对内联产生任何影响吗? 编辑:ID肯定是在编译时出现的,并且出现了多个“ 0”的实例(这就是为什么也要了解“ 8”的原因)。     

解决方法

没有。该函数是模板,因此必须内联,并且像这样的常量折叠是内联函数时最常见的优化之一。这表明,如果您使用的是现代编译器,则绝对没有任何区别。     ,首先,由于ID应该是
int
,因此模板应为
template<int ID,typename T>
A* Outer (T *p)
...
继续前进,尽管跌宕起伏,这取决于您的使用情况,但是这里有一些确定的事实: 性能 确实应该没有任何明显的区别。由于将为每个
ID
值创建一个新函数,因此它的执行就像您刚刚使用局部
ID
常量声明了自己的单独函数一样。因此,模板版本可能会更快,因为在函数调用时不会发生值的复制,但是就像我说的那样,它可能不足以构成破坏交易。 用法 这两种形式实际上并不等效。由于函数定义是在编译时根据
ID
的值定义的,因此只能使用编译时常量(这似乎是您所期望的)。在原始版本中,用户可以写
int i = 10;
Outer<Z>(new Z(5),i);
尽管
i
是一个变量,但会将其作为常量值复制到
ID
中。 在模板版本中,他们不能写
int i = 10;
Outer<i,Z>(new Z(5));
由于编译器会为每个
ID
值生成一个不同的函数,因此,当直到运行时才知道该值时,它不可能在编译时创建函数 因此,您的原始版本要灵活得多,而您建议的更改却非常严格。我认为大多数人都想以原始方式使用该函数,而不必强迫他们使用编译时常量。因此,我会坚持使用原始格式,除非出于某种原因您确实需要the11ѭ值作为编译时常量。 编译代码 对于已编译的代码,您的二进制文件会更大(假设您对ѭ11different的至少两个不同值使用该函数)。这是因为为程序中使用的ID的每个不同值创建了一个新函数。因此,如果您期望使用许多不同的值,则二进制文件中的膨胀可能会成为问题 内联 我没有明确的答案。我猜想如果内联受到影响,它可能会受到参数
T
而不是
ID
的影响。     ,假设您正确执行了此操作(代码具有相同的功能),那么引入的唯一代价就是编译时间的增加,因为编译模板所花的时间比编译正常函数所需的时间更长。 您可以说“我有超级快的计算机,而编译需要1/2秒”,但是对于大型项目而言,这很重要。     ,这将取决于您的编译器以及如何使用这些函数。 实际上,如果您已经进行了优化,那么唯一的 我想您会发现区别在于调用语法。但是如果 您遇到性能问题,配置文件,然后查看问题所在 来自(哪里。