c++ - 将普通功能更改为模板会产生任何正/负差异吗?

标签 c++ performance templates inline

我有一个包装函数(模板化)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/

相关文章:

c++ - "static"在声明全局模板函数的上下文中意味着什么?

c++ - 仅当模板参数具有成员函数时才启用成员函数

c++ - ActiveMQ C++ 同步客户端

c++ - vector 迭代器不兼容 : runtime error

c# - LINQ 中的多个 .Where() 语句是性能问题吗?

javascript - 如果函数被多次调用,在函数中缓存选择器是否性能更高?

c++ - 用模板参数填充容器

c++ - 使用模板的类型转换有奇怪的行为

c++ - 从动态 dll 访问静态链接库中的静态变量/函数

performance - 我们应该使用 _.foreach() 还是更好地使用 TypeScript 中的原生 for of 循环