有一个简单的 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) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。