Eigen使用场景:如何让类重载赋值运算符对raw方法返回值生效
解决方案
核心思路是通过返回代理对象而非直接返回内部值的引用,拦截对raw()返回值的赋值操作,转发到Parameter本身的赋值运算符走固定校验,同时完整保留对T类型成员方法的访问能力。
完整修改后的代码
template<typename T> struct Parameter { private: bool _fixed; T _value; // 嵌套代理类,拦截对raw返回值的赋值操作 struct RawProxy { Parameter<T>& parent; explicit RawProxy(Parameter<T>& p) : parent(p) {} // 重载赋值运算符,转发给外层Parameter的赋值逻辑,触发固定校验 RawProxy& operator=(const T& val) { parent = val; return *this; } // 重载->运算符,支持直接调用T的成员方法(如Eigen的array()、sum()等) T* operator->() { return &parent._value; } // const版本->运算符,适配const修饰的Parameter实例 const T* operator->() const { return &parent._value; } // 隐式转换为T的引用,适配需要传入T&/const T&参数的函数场景 operator T&() { return parent._value; } operator const T&() const { return parent._value; } }; public: std::string name; const bool* is_fixed = &_fixed; Parameter(std::string name, T value) : name(name), _value(value), _fixed(false) {} Parameter& operator=(const T& oValue){ if (_fixed){throw std::runtime_error("Error fixed value..");} _value = oValue; return *this; } void fix() { _fixed = true; } void unfix() { _fixed = false; } // 非const场景返回代理对象 RawProxy raw() { return RawProxy(*this); } // const场景直接返回const引用,天然禁止修改 const T& raw() const { return _value; } };
效果验证
修改后所有使用场景都符合预期:
std::string name = "A_Vector"; Eigen::RowVectorXd value = Eigen::RowVectorXd::Ones(1); Parameter<Eigen::RowVectorXd> param(name, value); // 正常调用Eigen原生方法,无影响 std::cout << param.raw().sum() << std::endl; // 给raw()返回值赋值会触发校验,未固定时可正常修改 param.raw() = Eigen::RowVectorXd::Ones(3); std::cout << param.raw().cols() << std::endl; // 输出3 // 固定参数 param.fix(); param.raw() = Eigen::RowVectorXd::Ones(5); // 此处抛出运行时异常,成功堵上绕过校验的漏洞
内容的提问来源于stack exchange,提问作者lefe
相关产品推荐
相关产品推荐

