通过引用传递的特征参数
Eigen parameters passing by reference
我正在关注 Eigen 文档中的此页面,试图了解 Eigen 参数的使用
https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html
以下代码按预期工作
#include <iostream>
#include <Eigen/Dense>
// a - nonwriteable, b - writeable
void eigen_reference_class(
const Eigen::Ref<const Eigen::Array<double,
Eigen::Dynamic, 3> >& a, Eigen::Ref<Eigen::Array<double, Eigen::Dynamic, 3> > b) {
b = 2 * a;
}
void eigen_reference(const Eigen::Array<double, 1, 3>& a, Eigen::Array<double, 1, 3>& b) {
b = 2*a;
}
template<typename Derived>
void eigen_template(const Eigen::PlainObjectBase<Derived>& a, Eigen::PlainObjectBase<Derived>& b) {
b = 2*a;
}
int main()
{
Eigen::Array<double, 1, 3> a, b, c, d;
a << 1, 2, 3;
eigen_reference_class(a, b);
eigen_reference(a, c);
eigen_template(a, d);
std::cout << "a : \n" << a << std::endl;
std::cout << "b: \n" << b << std::endl;
std::cout << "c: \n" << c << std::endl;
std::cout << "d: \n" << d << std::endl;
}
但是,如果数组的初始声明更改为
Eigen::Array<double, Eigen::Dynamic, 3> a, b, c, d;
那么程序将无法通过以下方式编译:
error: invalid initialization of non-const reference of type ‘Eigen::Array<double, 1, 3>&’ from an rvalue of type ‘Eigen::Array<double, 1, 3>’
eigen_reference(a, c);
即使仅保留 a
的定义,Or 也会因分段错误而失败。
我喜欢看看 int
在这种情况下的表现,因为它可以帮助我更轻松地理解在这种情况下发生的更复杂的事情。
假设你有一个 struct
持有一个 int
,它可以隐式转换为 int
,这样你就可以用它代替 int
,比如所以:
struct Integer {
int m_int;
operator int() { return m_int; }
};
现在定义两个函数,一个接受 int const &
,一个接受 int &
。
void const_ref(int const &) {}
void ref(int &) {}
如果我们在这些函数中使用常规整数,则不会有任何意外。
int j = 3;
const_ref(j);
ref(j);
但是如果我们改用 Integer
它就不会再编译了。
Integer i{2};
const_ref(i);
ref(i);
错误类似于
error: no matching function for call to 'ref'
ref(i);
^~~
note: candidate function not viable: no known conversion from 'Integer' to 'int &' for 1st argument
void ref(int &) {}
^
1 error generated.
现在的问题是,为什么 const_ref
有效而 ref
无效?
在对 const_ref
的调用中发生的是 int
的转换运算符被调用,returns 一个我们可以绑定常量的临时 int
参考。我们不能将可变引用绑定到这个临时对象,因为这会导致奇怪的效果。想象一下,函数 ref
修改了参数,但在这种情况下,它会修改一个临时变量,并且不会向您传入的原始 Integer
写入任何内容……这是一个有保证的错误。
在你的代码中是一样的。 Eigen::Array<double, Eigen::Dynamic, 3>
可以隐式转换为 Eigen::Array<double, 1, 3>
但您不能将可变引用绑定到临时引用。
我正在关注 Eigen 文档中的此页面,试图了解 Eigen 参数的使用
https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html
以下代码按预期工作
#include <iostream>
#include <Eigen/Dense>
// a - nonwriteable, b - writeable
void eigen_reference_class(
const Eigen::Ref<const Eigen::Array<double,
Eigen::Dynamic, 3> >& a, Eigen::Ref<Eigen::Array<double, Eigen::Dynamic, 3> > b) {
b = 2 * a;
}
void eigen_reference(const Eigen::Array<double, 1, 3>& a, Eigen::Array<double, 1, 3>& b) {
b = 2*a;
}
template<typename Derived>
void eigen_template(const Eigen::PlainObjectBase<Derived>& a, Eigen::PlainObjectBase<Derived>& b) {
b = 2*a;
}
int main()
{
Eigen::Array<double, 1, 3> a, b, c, d;
a << 1, 2, 3;
eigen_reference_class(a, b);
eigen_reference(a, c);
eigen_template(a, d);
std::cout << "a : \n" << a << std::endl;
std::cout << "b: \n" << b << std::endl;
std::cout << "c: \n" << c << std::endl;
std::cout << "d: \n" << d << std::endl;
}
但是,如果数组的初始声明更改为
Eigen::Array<double, Eigen::Dynamic, 3> a, b, c, d;
那么程序将无法通过以下方式编译:
error: invalid initialization of non-const reference of type ‘Eigen::Array<double, 1, 3>&’ from an rvalue of type ‘Eigen::Array<double, 1, 3>’
eigen_reference(a, c);
即使仅保留 a
的定义,Or 也会因分段错误而失败。
我喜欢看看 int
在这种情况下的表现,因为它可以帮助我更轻松地理解在这种情况下发生的更复杂的事情。
假设你有一个 struct
持有一个 int
,它可以隐式转换为 int
,这样你就可以用它代替 int
,比如所以:
struct Integer {
int m_int;
operator int() { return m_int; }
};
现在定义两个函数,一个接受 int const &
,一个接受 int &
。
void const_ref(int const &) {}
void ref(int &) {}
如果我们在这些函数中使用常规整数,则不会有任何意外。
int j = 3;
const_ref(j);
ref(j);
但是如果我们改用 Integer
它就不会再编译了。
Integer i{2};
const_ref(i);
ref(i);
错误类似于
error: no matching function for call to 'ref'
ref(i);
^~~
note: candidate function not viable: no known conversion from 'Integer' to 'int &' for 1st argument
void ref(int &) {}
^
1 error generated.
现在的问题是,为什么 const_ref
有效而 ref
无效?
在对 const_ref
的调用中发生的是 int
的转换运算符被调用,returns 一个我们可以绑定常量的临时 int
参考。我们不能将可变引用绑定到这个临时对象,因为这会导致奇怪的效果。想象一下,函数 ref
修改了参数,但在这种情况下,它会修改一个临时变量,并且不会向您传入的原始 Integer
写入任何内容……这是一个有保证的错误。
在你的代码中是一样的。 Eigen::Array<double, Eigen::Dynamic, 3>
可以隐式转换为 Eigen::Array<double, 1, 3>
但您不能将可变引用绑定到临时引用。