std::inner_product最省事实现点积,但需确保两向量等长、迭代器可解引用且支持+和*,自定义类型须重载对应运算符;叉积无标准库支持,仅适用于三维向量,需手写并注意坐标顺序与精度一致性。

点积用 std::inner_product 最省事,但得注意迭代器范围和数值类型
标准库的 std::inner_product 就是为点积设计的,不用手写循环。但它要求两个向量长度相等,且迭代器必须可解引用、支持 + 和 * 运算。
- 如果用
std::vector<double></double>,直接传begin()/end()即可;std::vector<int></int>也行,但结果类型默认是int,大数可能溢出 - 若向量长度不一致,
std::inner_product不报错,而是以较短者为准——容易漏掉数据,建议先加断言:assert(a.size() == b.size()) - 自定义类型(如带单位的向量)需重载
operator*和operator+,否则编译失败
std::vector<double> a = {1, 2, 3};
std::vector<double> b = {4, 5, 6};
double dot = std::inner_product(a.begin(), a.end(), b.begin(), 0.0); // 注意初始值用 0.0 而非 0叉积只能手写,且只对三维向量有意义
叉积(cross product)是几何运算,C++ 标准库没有提供,且仅对 3D 向量有定义。二维向量“叉积”其实是标量(a.x * b.y - a.y * b.x),常被误称为“伪叉积”,但不能和三维叉积混用。
- 输入必须是三个分量,少一个或多个都无意义;传入
std::vector时务必检查.size() == 3 - 返回类型应与输入一致:输入是
float,输出别用double,否则隐式转换可能掩盖精度问题 - 常见错误是把坐标顺序搞反,导致方向相反(右手系下,
a × b和b × a互为负向量)
struct Vec3 { float x, y, z; };
Vec3 cross(const Vec3& a, const Vec3& b) {
return {a.y*b.z - a.z*b.y,
a.z*b.x - a.x*b.z,
a.x*b.y - a.y*b.x};
}用 std::valarray 可简化基础运算,但不推荐用于生产环境
std::valarray 支持逐元素运算,写点积和叉积代码更紧凑,但它缺乏迭代器、不能和 STL 算法无缝协作,且多数编译器对其优化不佳。
- 点积可写成:
(a * b).sum(),但a和b必须同长,否则运行时报错(不是编译期) - 叉积无法单行表达,仍需手动计算三个分量,优势消失
- 调试困难:
valarray的 operatorstd::vector 或循环输出
Eigen 库是实际项目的首选,但引入前得确认构建系统支持
真正在做科学计算或图形学,别自己实现。Eigen 提供 .dot() 和 .cross(),类型安全、向量化优化、支持表达式模板。
立即学习“C++免费学习笔记(深入)”;
-
.cross()只接受Eigen::Vector3d等固定尺寸类型,传Vector4d直接编译失败,这是好事——避免逻辑错误 - 头文件-only,但需在 CMake 中启用
-march=native才能发挥 SIMD 加速;没开的话,性能可能不如手写循环 - 注意对齐:用
Eigen::Vector3d没问题,但自定义结构体包装后调用.cross()会失败,必须用 Eigen 原生类型
叉积的方向性、点积的数值稳定性,这些细节在接口层就卡死了,比自己写的自由函数可靠得多。


















