[英]Compilation Error Using template programming with Eigen C++ library
I downloaded Eigen (3) library and started using it. 我下载了Eigen(3)库并开始使用它。 I wrote a template function and declared a local variable of 'template type' inside the function.
我写了一个模板函数,并在函数内声明了一个'模板类型'的局部变量。 I am getting the following compilation error.
我收到以下编译错误。
$ g++ EigenTest.cpp
EigenTest.cpp: In instantiation of ‘void myFunc(Eigen::MatrixBase<Derived>&) [with Type1 = Eigen::Matrix<double, -1, -1>]’:
EigenTest.cpp:24:10: required from here
EigenTest.cpp:16:26: error: conversion from ‘Eigen::DenseCoeffsBase<Eigen::Matrix<double, -1, -1>, 1>::Scalar {aka double}’ to non-scalar type ‘Eigen::Matrix<double, -1, -1>’ requested
Type1 tmp = matrix(0, 0);
"EigenTest.cpp" is given below. “EigenTest.cpp”如下。
#include "Eigen/Dense"
#include <iostream>
template<typename Type1>
void myFunc(Eigen::MatrixBase<Type1>& matrix)
{
int i=matrix.rows();
Type1 tmp = matrix(0, 0); // getting compiler error here
std::cout<<"tmp is ->"<<tmp<<std::endl;
}
int main()
{
Eigen::MatrixXd m(2,2);
m.setConstant(100);
myFunc(m);
return 0;
}
I also tried using 'typename Type1 tmp = matrix(0, 0);' 我也尝试使用'typename Type1 tmp = matrix(0,0);'
This also didn't work! 这也行不通!
How to fix this? 如何解决这个问题? In normal C++ template programming (without Eigen), I can define a local variable inside a template function as 'Type1 tmp;"
在普通的C ++模板编程中(没有Eigen),我可以在模板函数中将局部变量定义为'Type1 tmp;'
In Eigen::MatrixBase<Type1>
, Type1
is not a scalar type but the type of the actual expression. 在
Eigen::MatrixBase<Type1>
, Type1
不是标量类型,而是实际表达式的类型。 In your example it will be MatrixXd but if myFunc is called on, eg, m.block(...), then Type1
will be a Block<...>. 在您的示例中,它将是MatrixXd,但如果调用myFunc,例如m.block(...),则
Type1
将是Block <...>。 To obtain the scalar type, you can use Type1::Scalar: 要获取标量类型,可以使用Type1 :: Scalar:
template<typename Type1>
void myFunc(Eigen::MatrixBase<Type1>& matrix)
{
typename Type1::Scalar Scalar;
Scalar tmp = matrix(0, 0);
}
And if you need a matrix type that is similar to Type1
, use Type1::PlainObject
, eg: 如果您需要一个类似于
Type1
的矩阵类型,请使用Type1::PlainObject
,例如:
typename Type1::PlainObject mat = 2 * matrix * matrix.transpose();
It looks like MatrixBase
uses the "CRTP" (see here ), the template argument is actually the type deriving from it. 看起来
MatrixBase
使用“CRTP”(参见此处 ),模板参数实际上是从中派生的类型。 Thus in your use of the method myFunc()
, Type1
is actually representing Eigen::MatrixXd
, and I think that you think Type1
is a double. 因此,在你使用方法
myFunc()
, Type1
实际上代表了Eigen::MatrixXd
,我认为 你认为Type1
是一个double。 So, this line: 所以,这一行:
Type1 tmp = matrix(0, 0);
In the documnetation for this library (see here ) the typedef for MatrixXd
is a matrix of doubles, so I guess the return from matrix(0, 0)
is a double, and as tmp is of Type1
which is Eigen::MatrixXd
, the one will not go into the other. 在这个库的documnetation中(见这里 ),
MatrixXd
的typedef是一个双精度矩阵,所以我猜matrix(0, 0)
的返回是一个double,而tmp是Type1
的Eigen::MatrixXd
,一个人不会进入另一个人。
Scanning the docummentation I think it MIGHT be better for your function to take a Matrix
as an argument, that way the scalar type should be available. 扫描docummentation我认为你的函数可能更好地将
Matrix
作为参数,这样标量类型应该是可用的。 Something like this: 像这样的东西:
template<class T, int rows, int cols, int opts, int maxR, int maxC >
void myFunc( Eigen::Matrix<T, rows, cols, opts, maxR, maxC>& matrix )
{
T tmp = matrix(0, 0);
}
(Looks dreadful though!!! ;-) ) (虽然看起来很可怕!!! ;-))
In your code, Type1
is deduced to be double
(because Eigen::MatrixXd
is defined that way ). 在你的代码中,
Type1
被推断为double
(因为Eigen::MatrixXd
是这样定义的 )。
You are then trying to do 你正在尝试做
Type1 tmp = matrix(0, 0);
And I'm afraid my Eigen knowledge isn't enough, so I ran it through Clang 3.3, and got this error: 而且我担心我的Eigen知识还不够,所以我通过Clang 3.3运行它,并得到了这个错误:
test.cpp:9:7: error: no viable conversion from 'Scalar' (aka 'double') to
'Eigen::Matrix<double, -1, -1, 0, -1, -1>'
Type1 tmp = matrix(0, 0); // getting compiler error here
^ ~~~~~~~~~~~~
test.cpp:17:1: note: in instantiation of function template specialization
'myFunc<Eigen::Matrix<double, -1, -1, 0, -1, -1> >' requested here
myFunc(m);
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:210:5: note: candidate constructor not viable:
no known conversion from 'Scalar' (aka 'double') to
'internal::constructor_without_unaligned_array_assert' for 1st argument
Matrix(internal::constructor_without_unaligned_array_assert)
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:284:25: note: candidate constructor not
viable: no known conversion from 'Scalar' (aka 'double') to 'const
Eigen::Matrix<double, -1, -1, 0, -1, -1> &' for 1st argument
EIGEN_STRONG_INLINE Matrix(const Matrix& other)
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:272:25: note: candidate template ignored:
could not match 'MatrixBase<type-parameter-0-0>' against 'double'
EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other)
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:292:25: note: candidate template ignored:
could not match 'ReturnByValue<type-parameter-0-0>' against 'double'
EIGEN_STRONG_INLINE Matrix(const ReturnByValue<OtherDerived>& other)
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:303:25: note: candidate template ignored:
could not match 'EigenBase<type-parameter-0-0>' against 'double'
EIGEN_STRONG_INLINE Matrix(const EigenBase<OtherDerived> &other)
^
1 error generated.
which is telling me you cannot call matrix
like that, with two 0's as arguments. 这告诉我你不能像这样调用
matrix
,用两个0作为参数。 It's also weird syntax because the MatrixBase
class does not have an operator()
which you seem to be trying to calling. 这也是一种奇怪的语法,因为
MatrixBase
类没有你似乎试图调用的operator()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.