微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C++ 将存储在共享指针向量中的函子应用到 Eigen unaryExpr

如何解决C++ 将存储在共享指针向量中的函子应用到 Eigen unaryExpr

我有一个函子对象的共享指针向量:std::vector<std::shared_ptr<MyFunctor>>,我想将其中一个应用于本征 MatrixXd 对象中的所有元素。

抽象基类 MyFunctor 定义了一个成员函数 operator(),它接受​​并返回一个 double 并且是常量。派生类实现该功能

看起来 unaryExpr 函数是合适的,但我不太明白语法正确。

我正在尝试执行以下操作:

mat.unaryExpr( *(vectorOfFunctors[0]) );

我正在添加一个示例,其中包含我发现可行的变通方法
这适用于 Windows 10、64 位上的 MSVC 2019 (16.2.5)。

#include <Eigen/Dense>
#include <vector>
#include <memory>

class MyFunctorBase {
public:
    virtual double operator()(double) const = 0;
    virtual std::string getName() const = 0;
};

class MyFunctor : public MyFunctorBase {
public:
    MyFunctor() {};
    std::string getName() const { return "MyFunctor"; }
    double operator()(double d) const { return d + 1; }
};

void func() {
    std::shared_ptr<MyFunctor> mf1(new MyFunctor());
    std::vector<std::shared_ptr<MyFunctorBase>> vectorOfFunctors;
    vectorOfFunctors.push_back(mf1);

    Eigen::MatrixXd A(2,2);
    A << 1,2,3,4;

    //Method 1
    //Eigen::MatrixXd t0 = A.unaryExpr(*(vectorOfFunctors[0]));    //Does not compile

    //Method 2
    const MyFunctorBase& mfb = *(vectorOfFunctors[0]);       //Compiles
    Eigen::MatrixXd t2 = A.unaryExpr(std::ref(mfb));
}

解决方法

Eigen 尝试实例化您传递给它的抽象函子的实例,因此编译错误。请注意,因为您取消引用该指针,所以您将切片的抽象对象传入 unaryExpr 方法。您可以直接传入派生函子,或者在取消引用之前将 dynamic_cast 传递给派生类型。

您使用 std::ref 获得预期行为的原因是它将 MyFunctorBase 包装在引用包装器中,因此在实例化时,您不会收到有关创建抽象的错误类型。稍后,当调用函子时,它会隐式转换为 MyFunctorBase&,从而允许虚拟 operator() 调用。继此之后,您可以拥有一个 std::vector 的引用包装对象 (std::vector<std::reference_wrapper<MyFunctorBase>>),而不是用 std::ref 手动包装容器中的每个元素。


请注意,特征矩阵提供了与 STL 算法兼容的迭代器,您可以使用 std::transform 实现相同的目标。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。