如何更简便地用Eigen::Vector4d实现3D向量以利用SIMD优化?
问题:用Eigen::Vector4d替代3D向量的便捷构造方案(G++/GCC环境)
环境:Windows 10 / eigen3 3.4.0-1 / MSYS2/MinGW64 13.1.0 / C++20
为利用SIMD向量化优化,计划用Eigen::Vector4d替代3D向量。最初通过typedef Eigen::Vector4d Vec3简化代码,但使用Vec3 u(1,2,3)构造时,编译器因缺少第四个参数报错,正确写法Vec3 u(1,2,3,4)又易造成混淆。
在MSVC编译器中可通过同名函数重载实现便捷构造:
typedef Eigen::Vector4d Vec3; inline Eigen::Vector4d Vec3(double x, double y, double z) { return Eigen::Vector4d(x, y, z, 0.0); } inline Eigen::Vector4d Vec3() { return Eigen::Vector4d(0.0, 0.0, 0.0, 0.0); } Vec3 v = Vec3(1,2,3); Vec3 w = Vec3();
但该特性在G++/GCC中不可用,目前的最终实现为:
typedef Eigen::Vector4d Vec3; inline Eigen::Vector4d Vec3Init(double x, double y, double z) { return Eigen::Vector4d(x, y, z, 0.0); } inline Eigen::Vector4d Vec3Init() { return Eigen::Vector4d(0.0, 0.0, 0.0, 0.0); } Vec3 v = Vec3Init(1,2,3); Vec3 w = Vec3Init();
请问有没有更简便的实现方式?
可行的优化方案
1. 继承Eigen::Vector4d并添加构造函数
直接继承Eigen::Vector4d,在子类中补充需要的构造函数,既保留原类所有功能,又能直接用Vec3(1,2,3)的直观写法构造:
class Vec3 : public Eigen::Vector4d { public: // 空构造:默认初始化全0 Vec3() : Eigen::Vector4d(0.0, 0.0, 0.0, 0.0) {} // 3参数构造:自动将第四个分量设为0 Vec3(double x, double y, double z) : Eigen::Vector4d(x, y, z, 0.0) {} // 继承父类的其他构造函数(如4参数、拷贝构造等) using Eigen::Vector4d::Vector4d; }; // 使用示例 Vec3 v(1,2,3); Vec3 w; Vec3 u(1,2,3,4); // 仍支持原4参数构造逻辑
这种方式完全兼容G++/GCC,写法和你最初的预期一致,代码可读性更高。
2. 用命名空间隔离重载函数
如果不想用继承,可以把构造逻辑放到自定义命名空间中,避免和typedef的Vec3名称冲突:
namespace MyMath { using Vec3 = Eigen::Vector4d; inline Vec3 make_vec3(double x, double y, double z) { return Vec3(x, y, z, 0.0); } inline Vec3 make_vec3() { return Vec3(0.0, 0.0, 0.0, 0.0); } } // 使用示例 using namespace MyMath; Vec3 v = make_vec3(1,2,3); Vec3 w = make_vec3();
命名空间可以有效隔离名称,G++/GCC能正确解析函数重载,同时避免和类型名冲突。
3. 利用C++20的工厂函数+自动推导
依托C++20的特性,用工厂函数结合auto推导类型,写法更简洁:
using Vec3 = Eigen::Vector4d; inline Vec3 Vec3(double x, double y, double z) { return Eigen::Vector4d(x, y, z, 0.0); } inline Vec3 Vec3() { return Eigen::Vector4d(0.0, 0.0, 0.0, 0.0); } // 使用示例 auto v = Vec3(1,2,3); // v的类型自动推导为Vec3 Vec3 w = Vec3(); // 也可显式指定类型
这种方式不需要额外的类或命名空间,直接通过函数重载实现,G++/GCC在C++20模式下可以正常编译。
内容的提问来源于stack exchange,提问作者Prashant
相关产品推荐
相关产品推荐

