在 Eigen 中使用 CwiseBinaryOp 时如何摆脱 "invalid use of incomplete type"
How to get rid of "invalid use of incomplete type" when using CwiseBinaryOp in Eigen
我正在尝试用我自己的函数替换 Eigen 中 3x1 向量求和的函数。例如,
Matrix<float, 3, 1> q, q2, q3;
q.setRandom();
q2.setRandom();
q3.setRandom();
q3 = q + q2;
希望q3是自己函数计算出来的
由于 Eigen 实际上是通过 operator= 而不是 operator+ 来计算总和,而 operator+ 只是 returns 一个 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;
我想知道为什么会出现这个错误以及如何消除它。
我不确定你这边出了什么问题,但我通过以下方式让它工作:
MatrixAddons.h
这是 header,其中包含您打算放置在 Eigen::Matrix
class.
中的 operator=
的定义
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
Header 定义 EIGEN_MATRIX_PLUGIN
指向 MatrixAddons.h header.
#define EIGEN_MATRIX_PLUGIN "MatrixAddons.h"
main.cpp
用于测试 expanded Eigen::Matrix
class.
的 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
语句的一部分被调用。
使用 g++,尝试 运行 预处理器 (-E
)。检查输出时,您会注意到 operator=
函数出现在 Matrix class 定义的中间(class 声明从大约 500 行开始)。 CwiseBinaryOp
class 的声明出现在上方(在其上方约 5,000 行)但未定义。对于您的版本,编译器需要在 operator=
函数中使用 CwiseBinaryOp
的定义,但尚未定义。它适用于 MSVC 而不是 g++ 的原因可能是由于 MSVC 的 "broken" 两阶段模板名称查找(我对此可能是错误的。参见 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=
函数在 CwiseBinaryOp
class 的定义之后(大约 3,000 行之后)首次使用时才会 "defined" operator=
定义)。
我正在尝试用我自己的函数替换 Eigen 中 3x1 向量求和的函数。例如,
Matrix<float, 3, 1> q, q2, q3;
q.setRandom();
q2.setRandom();
q3.setRandom();
q3 = q + q2;
希望q3是自己函数计算出来的
由于 Eigen 实际上是通过 operator= 而不是 operator+ 来计算总和,而 operator+ 只是 returns 一个 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;
我想知道为什么会出现这个错误以及如何消除它。
我不确定你这边出了什么问题,但我通过以下方式让它工作:
MatrixAddons.h
这是 header,其中包含您打算放置在 Eigen::Matrix
class.
operator=
的定义
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
Header 定义 EIGEN_MATRIX_PLUGIN
指向 MatrixAddons.h header.
#define EIGEN_MATRIX_PLUGIN "MatrixAddons.h"
main.cpp
用于测试 expanded Eigen::Matrix
class.
#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
语句的一部分被调用。
使用 g++,尝试 运行 预处理器 (-E
)。检查输出时,您会注意到 operator=
函数出现在 Matrix class 定义的中间(class 声明从大约 500 行开始)。 CwiseBinaryOp
class 的声明出现在上方(在其上方约 5,000 行)但未定义。对于您的版本,编译器需要在 operator=
函数中使用 CwiseBinaryOp
的定义,但尚未定义。它适用于 MSVC 而不是 g++ 的原因可能是由于 MSVC 的 "broken" 两阶段模板名称查找(我对此可能是错误的。参见 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=
函数在 CwiseBinaryOp
class 的定义之后(大约 3,000 行之后)首次使用时才会 "defined" operator=
定义)。