如何在 Eigen 中的元素明智操作中使用派生函子
How to use a derived functor in element wise operation in Eigen
我想概括所有我需要的自定义元素智能仿函数,它们都来自提供 operator() 方法的公共基础 class。这样我就可以简单地声明一个指向基 class 的变量,当我调用 operator() 方法时,每个派生的 class 都有自己的实现。不幸的是,我尝试了不同的方法,但我不断遇到一些(对象切片?)错误。这是一个代码示例:
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/Core>
class Base {
public:
virtual float operator()(const float& x) const = 0;
};
class Derived : public Base {
public:
float operator()(const float& x) const;
};
float Derived::operator()(const float& x) const {
std::cout << "Derived::operator()\n"; // you may want to toggle this
return x;
}
int main() {
Eigen::MatrixXf m(2, 2);
m << 0.0f, 1.0f, -2.0f, 3.0f;
std::cout << std::endl << m.unaryExpr(Derived()) << std::endl; // this works
// but in a real world scenario I have different functors inheriting from Base
// and I would like to have a generic way to use them, like the following:
Base* B = new Derived();
std::cout << std::endl << (*B)(1.0f) << std::endl; // just a test, it correctly calls the Derived version of operator()
// this doesn't work
// from what I understand it's trying to create a Base object which of course results in an
// error since is abstract, also when I tested with a non abstract version of Base it tried to
// call the virtual Base::operator() instead of the derived
std::cout << std::endl << m.unaryExpr(*B) << std::endl;
return 0;
}
我试着查看文档 https://tmp.mosra.cz/eigen-docs/classEigen_1_1DenseBase.html#af49806260cbfdd0be63e865367e48482 但我找不到问题所在。
感谢任何帮助。
默认情况下 unaryExpr
按值获取其参数,这意味着它将尝试复制 *B
。由于类型的原因,它将调用 Base
.
的复制构造函数
这种行为通常不是人们想要的,当它影响数据成员时被描述为 "Object slicing"(尽管在这种情况下没有数据丢失,它只是没有使用您期望的 vritual 函数重载)。
绕过仿函数复制的一种简单方法是使用std::ref
。
喜欢m.unaryExpr(std::ref(*B))
。这样只会复制一个引用包装器,而底层对象仍然是您构造的对象。
我想概括所有我需要的自定义元素智能仿函数,它们都来自提供 operator() 方法的公共基础 class。这样我就可以简单地声明一个指向基 class 的变量,当我调用 operator() 方法时,每个派生的 class 都有自己的实现。不幸的是,我尝试了不同的方法,但我不断遇到一些(对象切片?)错误。这是一个代码示例:
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/Core>
class Base {
public:
virtual float operator()(const float& x) const = 0;
};
class Derived : public Base {
public:
float operator()(const float& x) const;
};
float Derived::operator()(const float& x) const {
std::cout << "Derived::operator()\n"; // you may want to toggle this
return x;
}
int main() {
Eigen::MatrixXf m(2, 2);
m << 0.0f, 1.0f, -2.0f, 3.0f;
std::cout << std::endl << m.unaryExpr(Derived()) << std::endl; // this works
// but in a real world scenario I have different functors inheriting from Base
// and I would like to have a generic way to use them, like the following:
Base* B = new Derived();
std::cout << std::endl << (*B)(1.0f) << std::endl; // just a test, it correctly calls the Derived version of operator()
// this doesn't work
// from what I understand it's trying to create a Base object which of course results in an
// error since is abstract, also when I tested with a non abstract version of Base it tried to
// call the virtual Base::operator() instead of the derived
std::cout << std::endl << m.unaryExpr(*B) << std::endl;
return 0;
}
我试着查看文档 https://tmp.mosra.cz/eigen-docs/classEigen_1_1DenseBase.html#af49806260cbfdd0be63e865367e48482 但我找不到问题所在。 感谢任何帮助。
默认情况下 unaryExpr
按值获取其参数,这意味着它将尝试复制 *B
。由于类型的原因,它将调用 Base
.
这种行为通常不是人们想要的,当它影响数据成员时被描述为 "Object slicing"(尽管在这种情况下没有数据丢失,它只是没有使用您期望的 vritual 函数重载)。
绕过仿函数复制的一种简单方法是使用std::ref
。
喜欢m.unaryExpr(std::ref(*B))
。这样只会复制一个引用包装器,而底层对象仍然是您构造的对象。