有一个简单的 C++函数
divide
用于将整数范围内的所有值相除:void divide(std::span<int> i, int d)
,通过循环将每个值除以d
。- 整数除法是昂贵的操作,若除数
d
在编译时已知,函数可更快,如d
为 2 时,编译器可能优化为移位等操作。
可将除法参数变为模板参数:
template <int d> void divide(std::span<int> i)
,模板函数不是函数而是生成函数的“食谱”,提供整数d
时创建函数,使编译器能处理编译时常量生成更快代码。
若期望除数在 2 到 6 之间,可从通用函数调用模板函数:
void divide_fast(std::span<int> i, int d)
,通过一系列if
判断调用不同的模板函数divide<d>
,编译器可生成高效代码。- 也可用
switch/case
,但不能显著简化代码,编译器可通过一系列if
从句(如跳转表)生成高效代码。
用 lambda 函数隐藏模板函数的混乱优化:
auto f = [&i]<int divisor>() { for (auto& value : i) { value /= divisor; } };
,通过if
判断调用不同的lambda
函数f.operator()<d>
。- 但给定模板 lambda 表达式,不能直接传递模板参数,需通过特殊化模板
operator()<params>
实现。
特定情况下不用模板也可得到相同编译输出:
void divide_fast_simple(std::span<int> i, int d)
,定义一个普通 lambda 函数[&i](int divisor)
,通过if
判断调用不同的普通函数f(divisor)
。
在另一端,Paul Dreik 建议用模板元编程和折叠表达式:
void divide_fast(std::span<int> i, int d)
,通过复杂的模板元编程代码实现根据不同除数进行相应操作,在更具挑战性的问题中模板元编程很有用,但此例可能过度。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。