如何在 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))。这样只会复制一个引用包装器,而底层对象仍然是您构造的对象。