我有一个包装函数(模板化)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()
原型(prototype)为,
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
的影响。
关于c++ - 将普通功能更改为模板会产生任何正/负差异吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6093086/