为什么要将值传递给模板,而不是在函数调用中提供

Why pass a value to a template instead of supplying it in a function call?

本文关键字:函数调用 值传 为什么      更新时间:2023-10-16

在我学习c++的过程中,有一个概念我不能完全掌握和理解机制背后的原因。这个主题是:函数模板和在编译时传递参数,而不是在运行时传递参数。

我想知道的是,在编译时传递int值的设计背后的原因。我认为c++的开发者有可能允许在运行时传递值,但我想知道的是——选择在编译时传递值的原因,比如说int。当然,我说的是像这样的函数模板:

#include <iostream>
using namespace std;
template <class T, int N>
T fixed_multiply (T val)
{
  return val * N;
}
int main() {
  std::cout << fixed_multiply<int,2>(10) << 'n';
  std::cout << fixed_multiply<int,3>(10) << 'n';
}

据我所知,在调用模板函数时赋值的int值(在本例中为<2>和<3>)是在编译时计算的。这些机制设计背后的原因是什么?我理解它是创建每个函数的不同实例,一个乘以2,一个乘以3,分别。因此,它不能传递变量,而必须传递常量。

但是为什么这是必要的呢?我觉得设计师可以允许运行时执行,这样传递给它的值就可以是变量,但显然设计师认为这样会更好。

谢谢。

有时,当其中一个操作数是已知常数时,可以进行更多的优化。

例如,在x86架构上,乘(常数)3可以用LEA指令实现,它的运行速度比IMUL快得多。无符号整数变量除以2的常数幂可以用右移位来代替(并且用与与取模)。

假设你必须将一个向量的所有元素乘以2,并且你有一个变换向量所有元素的算法。

算法可以用一个接受一个参数的函数来定制

但是你有带参数的乘法…因此,您可以将一个参数绑定到联系人(在编译时),并有效地创建一个单参数函数

传递整型值或浮点值(很少)或其他值作为模板参数的主要原因是它们在问题中表示不同的类型。他们希望有可重用的方法和算法来操作这些类型。

从设计的角度来看,以Boost Multi Array为例。这是一个设计用来支持n维数组的系统。所以当你定义

typedef boost::multi_array<double, 3> array_3d;
typedef boost::multi_array<double, 2> array_2d;

它们是两种完全不同的类型。有人可以编写一个特殊的迭代器,它接受一个multi_array<type, int>,而不必为2d和3d情况重新定义它。

可能有代码库按照你列出的方式优化它们的函数,但这些都是例外。当模板化任何东西时,优化并不是主要的动机,而拥有一个模块化的、可重用的、通用的代码才是。