为什么要将值传递给模板,而不是在函数调用中提供
Why pass a value to a template instead of supplying it in a function call?
在我学习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情况重新定义它。
可能有代码库按照你列出的方式优化它们的函数,但这些都是例外。当模板化任何东西时,优化并不是主要的动机,而拥有一个模块化的、可重用的、通用的代码才是。
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 为用户定义的类正确调用复制构造函数/赋值运算符
- VkSurfaceKHR 指针的值在函数调用后更改,无需任何显式赋值
- 了解在返回值之前和之后使用 EAX 的函数调用
- 使用成员初始值设定项列表时没有匹配的函数调用错误
- 将值推送到 getter 函数调用的列表中时出现问题
- 调用值构造函数而不是复制构造函数
- 当值传递给C++中的运算符重载函数时会发生什么
- 构造函数初始值设定项列表未调用复制构造函数
- 如果函数按值传递并按值返回,将调用复制构造函数多少次
- 地址处的 C++ 值与函数调用后的预期值不同
- 使用赋值运算符将宏转换为函数调用
- 尝试将参数包的第一个元素作为函数调用,并将包的其余部分作为参数传递给它
- 在 OOP 中,调用函数返回值还是直接调用值更快?
- std::tie 在从函数调用传递值时失败,并显示"无法绑定非常量左值引用"
- 构造函数的初始值设定项列表中的函数调用是否按顺序排序?
- 枚举值依赖函数调用
- 为循环中多次调用的函数返回值预分配内存的正确方法是什么