表达式模板通过CRTP构建编译期表达式树,延迟向量加法求值,避免临时对象与多次循环,实现零成本抽象与循环融合。

表达式模板(Expression Templates)是一种在编译期优化数值计算的技术,常用于高性能计算库(如Eigen、Blaze)中实现延迟求值和消除临时对象。它的核心思想是:将数学表达式构建成一个模板表达式树,在运行时才真正求值,从而避免中间结果的创建。
基本动机:避免临时对象
考虑两个向量相加:
Vector a, b, c, d;
d = a + b + c;
如果没有表达式模板,每次 + 都会生成一个临时 Vector 对象,导致多次内存分配和拷贝。而表达式模板可以让编译器“看到”整个表达式结构,在最终赋值时一次性计算,跳过中间临时变量。
实现一个简单的向量加法表达式模板
我们从一个简化的例子开始,实现支持延迟加法的向量类型。
立即学习“C++免费学习笔记(深入)”;
1. 定义基础向量类
template
struct Vector {
std::vector data;
Vector(int n) : data(n) {}
int size() const { return data.size(); }
T& operator[](int i) { return data[i]; }
const T& operator[](int i) const { return data[i]; }
};
2. 定义表达式基类(CRTP)
template
struct Expr {
const E& self() const { return static_cast(*this); }
};
这里使用了CRTP(奇异递归模板模式),让基类能访问派生类的类型信息,而无需虚函数开销。
3. 定义加法表达式类型
template
struct AddExpr : Expr> {
const LHS& lhs;
const RHS& rhs;
AddExpr(const LHS& l, const RHS& r) : lhs(l), rhs(r) {}
// 延迟求值:只在需要时计算
auto operator[](int i) const { return lhs[i] + rhs[i]; }
int size() const { return lhs.size(); }
};
4. 重载操作符 +
template
auto operator+(const Expr& lhs, const Expr& rhs) {
return AddExpr(lhs.self(), rhs.self());
}
注意:所有表达式类型都继承自 Expr,所以这个 + 能接受任意组合的表达式。
5. 让 Vector 成为表达式
template
struct Vector : Expr> {
… // 同上
};
现在 Vector 也成了表达式类型,可以参与表达式构建。
6. 实现赋值操作以触发求值
template
Vector& operator=(Vector& vec, const Expr& expr) {
auto& e = expr.self();
for (int i = 0; i vec[i] = e[i];
}
return vec;
}
现代C++中可写成泛型 lambda 形式,或使用具体模板参数替代 auto。
实际使用与效果
Vector a(1000), b(1000), c(1000), d(1000);
// … 初始化
d = a + b + c;
这行代码的执行过程:
a + b 返回一个 AddExpr再与 c 相加,返回 AddExpr, Vector>赋值时遍历一次,计算 (a[i] + b[i]) + c[i]
全程没有构造临时 Vector 对象,循环合并为一次,实现“循环融合”(loop fusion)。
扩展与注意事项
真实场景中还需考虑:
支持更多操作(减法、标量乘法、点积等)处理别名问题(Aliasing),必要时强制求值表达式深度过大可能导致编译时间变长或栈溢出调试困难:表达式类型名非常复杂
基本上就这些。表达式模板本质是把运行时的计算调度提前到编译期建模,用模板实例化代替临时对象,是C++零成本抽象的典范之一。不复杂但容易忽略细节。
以上就是C++怎么实现一个表达式模板(Expression Templates)_C++高性能计算与延迟求值的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1487101.html
微信扫一扫
支付宝扫一扫