Eigen函数返回传入同矩阵对象时遇保护构造函数错误问题
Eigen函数模板返回原对象时的protected构造函数错误解析与解决方法
错误原因
Eigen的ArrayBase<Derived>是专为表达式模板设计的抽象基类,它的构造函数被声明为protected,目的就是禁止直接实例化基类对象。当你写return x;时,编译器会自动推导返回类型为Eigen::ArrayBase<Derived>,然后尝试用传入的基类引用x构造一个基类实例——但基类的拷贝构造是受保护的,因此触发编译错误。
正确解决方法
要返回传入的原对象(实际类型是Derived),需要明确让编译器推导或指定正确的返回类型,而非基类ArrayBase<Derived>:
方案1:返回原对象的const引用(无拷贝,推荐)
如果不需要拷贝原对象,直接返回原对象的const引用即可,通过静态转换将基类引用转为实际派生类引用:
template <typename Derived> const Derived& myFun(const Eigen::ArrayBase<Derived>& x) { return static_cast<const Derived&>(x); }
这里的静态转换是安全的,因为x本质上就是Derived类型对象的基类引用。
方案2:返回原对象的拷贝
如果需要返回原对象的副本(比如原对象是临时值场景),可以指定返回类型为Derived:
template <typename Derived> Derived myFun(const Eigen::ArrayBase<Derived>& x) { return static_cast<const Derived&>(x); }
对你的规避方案的分析
你用x.matrix().array()的方式确实能绕过错误,这是因为:
x.matrix()会返回一个适配Array为Matrix的表达式模板对象MatrixWrapper<const Derived>- 再调用
.array()会将其转回Array类型的表达式模板对象
Eigen的表达式模板机制会在编译期优化掉这些无意义的转换操作,最终生成的代码和直接返回原对象完全一致,不会有额外性能开销。但这个方案属于间接规避,不如直接静态转换的写法清晰直观。
内容的提问来源于stack exchange,提问作者marco
相关产品推荐
相关产品推荐

