将正常函数更改为模板将产生任何正/负差异
Changing a normal function to template will make any positive/negative difference?
我有一个包装函数(模板化)Outer()
和核心功能函数Inner()
。
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传递。因此,我正在考虑将Outer()
原型更改为
template<int ID, typename T>
A* Outer (T *p)
{
return Inner (p, p->value, ID);
}
将用作
A *pz = Outer<333>(new Z(5));
想知道的是,新方法是否对代码/性能级别有任何影响?是否会对内联产生任何影响?
编辑:ID肯定在编译时,并且出现了几个Outer()
实例(这就是为什么了解inline
也很重要)。
首先,由于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
的每个值生成不同的函数,因此在运行时之前不知道值的情况下,它不可能在编译时创建函数
因此,您的原始版本要灵活得多,而您提出的更改则非常严格。我认为大多数人都希望以原始的方式使用该函数,这样他们就不会被迫使用编译时间常数。因此,除非出于某种原因,真的需要ID
值作为编译时常数,否则我会坚持使用原始值。
编译代码
对于编译后的代码,您的二进制文件将更大(假设您对ID
的至少两个不同值使用该函数)。这是因为程序中使用的ID的每个不同值都会创建一个新函数。因此,如果你期望使用许多不同的值,二进制文件中的膨胀可能会成为的一个问题
内衬
这是一个我没有明确答案的问题。我猜如果内联受到影响,它可能会受到参数T
而不是ID
的影响。
无。函数是一个模板,因此必须内联,而像这样的常量折叠是内联函数时最常见的优化之一。这表明,如果你有一个现代编译器,它绝对不会有任何区别。
假设你做得正确(代码具有相同的功能),那么引入的唯一惩罚就是编译时间的增加,因为编译模板比编译正常函数需要更长的时间。
你可以说"我有超高速的计算机,编译需要1/2秒",但对于大项目来说,这很重要。
这将取决于编译器和函数的使用方式。在实践中,如果你已经进行了优化不同之处在于调用语法。但是如果您有性能问题,请分析并查看问题所在来自。
- 不执行任何操作的函数调用C++
- 标准库中的任何正则表达式语法是否支持 (?(定义)用于子模式参考?
- 是否有任何内置函数可以检查给定的两个数字在给定整数数组中的顺序是否相同?
- 适用于 gcc 4.8 的任何正则表达式库
- 如何处理不保证返回任何内容的函数
- 如何在C++中接收任何类型的函数参数并获取函数内传递变量的类型?
- 如何在C++变量中存储任何类型的函数
- 浮点计算可以用于任何可靠的函数,特别是容器和算法吗?
- 是否有任何内置函数可以告诉编译器分支是否可预测
- 正在可能将任何类型的函数存储在一个可能的变量中
- 使用std ::函数在对象列表上调用任何对象成员函数
- 确定C++中用户输入的类型,而无需任何标准库函数
- 来自没有默认构造函数的超级类的子类,而无需调用任何其他构造函数
- 是否有任何等效的 C/C 函数 IdnMapping::GetAscii C# Methode
- 接受任何类型的函数作为参数的类C++
- 重定向是否有任何回调函数
- 为什么std::vector::template在没有调用任何复制构造函数的情况下调用析构函数
- 指向任何具有匹配函数签名的类的成员函数的C++指针
- 从函数返回向量<向量<int>>是否会调用 C++11 中的任何移动构造函数
- 将正常函数更改为模板将产生任何正/负差异