在Eigen

时间:2015-10-22 16:47:33

标签: c++ templates operator-overloading eigen

我正在尝试用我自己的函数替换Eigen中3x1 Vector之和的函数。例如,

Matrix<float, 3, 1> q, q2, q3;
q.setRandom();
q2.setRandom();
q3.setRandom();
q3 = q + q2;

我希望q3是由我自己的函数计算的。

由于Eigen实际上是通过operator =而不是operator +来计算和,而operator +只返回一个CwiseBinaryOp对象,我需要重载operator =。

现在我正在使用EIGEN_MATRIX_PLUGIN marco将我的代码添加到Eigen的Matrix.h中:

inline Matrix<float, 3, 1> &operator=(
const CwiseBinaryOp<internal::scalar_sum_op<float>, const Matrix<float, 3, 1>, const Matrix<float, 3, 1>>
    &op) {
    float *t = m_storage.data();
    op.lhs(); //error here
    return *this;
}

我自己的函数需要访问指向q,q2和q3数据的指针。但是在尝试通过CwiseBinaryOp对象访问q和q2的数据时出现以下错误。

In file included from /home/tong/Program/Eigen/Eigen/src/Core/Matrix.h:340:0,
                 from /home/tong/Program/Eigen/Eigen/Core:294,
                 from /home/tong/Program/Eigen/Eigen/Dense:1,
                 from /home/tong/ClionProjects/EigenTest/main.cpp:7:
/home/tong/ClionProjects/EigenTest/MatrixAddon.h: In member function ‘Eigen::Matrix<float, 3, 1>& Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::operator=(const Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<float>, const Eigen::Matrix<float, 3, 1>, const Eigen::Matrix<float, 3, 1> >&)’:
/home/tong/ClionProjects/EigenTest/MatrixAddon.h:12:7: error: invalid use of incomplete type ‘const class Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<float>, const Eigen::Matrix<float, 3, 1>, const Eigen::Matrix<float, 3, 1> >’
     op.lhs();
       ^
In file included from /home/tong/Program/Eigen/Eigen/Core:252:0,
                 from /home/tong/Program/Eigen/Eigen/Dense:1,
                 from /home/tong/ClionProjects/EigenTest/main.cpp:7:
/home/tong/Program/Eigen/Eigen/src/Core/util/ForwardDeclarations.h:89:65: error: declaration of ‘const class Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<float>, const Eigen::Matrix<float, 3, 1>, const Eigen::Matrix<float, 3, 1> >’
 template<typename BinaryOp,  typename Lhs, typename Rhs>  class CwiseBinaryOp;

我想知道为什么会出现这个错误以及如何摆脱它。

2 个答案:

答案 0 :(得分:1)

我不确定你身边出了什么问题,但是我让它以下列方式工作:

<强> MatrixAddons.h

这是包含您要在operator=课程中放置的Eigen::Matrix定义的标头。

Matrix<float, 3, 1>& operator=(
    const CwiseBinaryOp<internal::scalar_sum_op<float>, const Matrix<float,
    3, 1>, const Matrix<float, 3, 1>>& op)
{
    float *t = m_storage.data();
    op.lhs();
    return *this;
}

<强>的config.h

定义EIGEN_MATRIX_PLUGIN以指向 MatrixAddons.h 标题的标头。

#define EIGEN_MATRIX_PLUGIN "MatrixAddons.h"

<强>的main.cpp

用于测试扩展 Eigen::Matrix类的C ++源代码。

#include <iostream>
#include "config.h"
#include "Eigen/Core"

int main()
{
    Eigen::Matrix<float, 3, 1> q1, q2, q3;
    q1.setRandom();
    q2.setRandom();
    q3 = q1 + q2;
    std::cout << q3 << std::endl;
}

一些调试(或从新operator=记录)显示新添加的运算符是q3 = q1 + q2语句的一部分。

答案 1 :(得分:0)

使用g ++,尝试只运行预处理器(-E)。在检查输出时,您会注意到您的operator=函数出现在Matrix类的定义中间(类声明开始大约500行)。 CwiseBinaryOp类的声明出现在上面(大约5,000行以上),但未定义。对于您的版本,编译器需要在CwiseBinaryOp函数中使用operator=的定义,但尚未定义。它与MSVC而不是g ++一起使用的原因可能是由于MSVC&#34;&#34;破坏&#34;两阶段模板名称查找(我可能错了。参见例如here,为什么MSVC接受代码而不是g ++)。

你可以通过改变它来获得g ++来编译你的函数:

template <typename T>
Matrix<T, 3, 1>& operator=(
    const CwiseBinaryOp<
        internal::scalar_sum_op<T>,
        const Matrix<T, 3, 1>,
        const Matrix<T, 3, 1>
        > & op)
{
    std::cout << "Custom thingy\n";
    T *t = m_storage.data();
    op.lhs();
    return *this;
}

在这种情况下,operator=功能不是&#34;定义&#34;直到它首次使用,这是在CwiseBinaryOp类定义之后(operator=定义之后大约3,000行)。