将 coeffRef 与 const CwiseUnaryView 一起使用 - 将两个 CWiseUnaryView



我将coeffRef()CWiseUnaryView函数一起使用时遇到了一些问题,但前提是该函数被声明为const

可重现的示例:

#include <Eigen/Core>
struct dummy_Op {
  EIGEN_EMPTY_STRUCT_CTOR(dummy_Op)
  EIGEN_DEVICE_FUNC
  EIGEN_STRONG_INLINE const double& 
    operator()(const double &v) const { return v; }
  EIGEN_DEVICE_FUNC
  EIGEN_STRONG_INLINE double& 
    operator()(double &v) const { return v; }
};
void foo(Eigen::MatrixXd &out)
{
    //Compiles
    Eigen::CwiseUnaryView<dummy_Op, Eigen::MatrixXd> view(out);
    view.coeffRef(0,0);
    //Doesn't Compile
    const Eigen::CwiseUnaryView<dummy_Op, Eigen::MatrixXd> const_view(out);
    const_view.coeffRef(0,0);
}

返回:

<source>: In function 'void foo(Eigen::MatrixXd&)':
<source>:21:28: error: passing 'const Eigen::CwiseUnaryView<dummy_Op, 
Eigen::Matrix<double, -1, -1> >' as 'this' argument discards qualifiers 
[-fpermissive]
     const_view.coeffRef(0,0);
                            ^
In file included from /opt/compiler-explorer/libs/eigen/v3.3.4/Eigen/Core:413,
                 from <source>:1:
/opt/compiler-explorer/libs/eigen/v3.3.4/Eigen/src/Core/DenseCoeffsBase.h:340:33: note:   
in call to 'Eigen::DenseCoeffsBase<Derived, 1>::Scalar& 
Eigen::DenseCoeffsBase<Derived, 1>::coeffRef(Eigen::Index, Eigen::Index) 
[with Derived = Eigen::CwiseUnaryView<dummy_Op, Eigen::Matrix<double, 
-1, -1> >; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = double; Eigen::Index = long int]'
     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
                                 ^~~~~~~~
Compiler returned: 1

编译器资源管理器:https://godbolt.org/z/kPHPuC

这样做的副作用是两个(非常量(CWiseUnaryViews的乘法也失败,请参阅以下示例:https://godbolt.org/z/JYQb3d

底线是你正在调用常量实例的非常量方法。被调用的(第一个(coeffRef是DenseCoeffsBase.h(DenseCoeffsBase<Derived, WriteAccessors>(中的一个(也是唯一一个(,它不合格。DenseCoeffsBase<Derived, ReadOnlyAccessors>类没有coeffRef方法。如果启用 -fpermissive 编译器标志,则可以绕过此错误(并收到警告(。

在密集的情况下,您可能仍然希望使用 operator()(Index, Index) 方法,该方法确实具有 const 限定版本。我刚刚注意到文档明确表示无论如何都要使用该方法,即使对于非 const 版本也是如此。这显然不会返回 const 引用,但至少在您的示例中作为双精度,它应该不会太重要。

CwiseUnaryView旨在

用于类似 L 值的表达式,例如

MatrixXcd A;
A.real() = something; // `A.real()` is writable

如果要应用元素级函子并将其用作 R 值,则应改用CwiseUnaryOp

void foo(Eigen::MatrixXd &out)
{
    Eigen::CwiseUnaryOp<dummy_Op, Eigen::MatrixXd> view1(out);
    // shorter:
    auto view2 = out.unaryExpr(dummy_Op());
    Eigen::MatrixXd result = view1 * view2;
    // or directly write: out.unaryExpr(dummy_Op()) * out.unaryExpr(dummy_Op());
}

相关内容

  • 没有找到相关文章

最新更新