c++ - 用 Boost.Python 包装 Eigen 的 operator()() 时的重载分辨率

标签 c++ c++11 eigen boost-python

我正在使用 Boost.Python 包装 C++ 库。其中的一些函数返回 Eigen::MatrixXd 对象(dynamically sized double-precision matrix class)。在 Python 方面,我只需要访问矩阵的维度,这很容易,并使用 Eigen 的重载 operator()() 方法检索一些矩阵元素。不幸的是,有 4 个这样的重载方法,必须手动选择正确的方法,即给 Boost.Python 一个具有正确签名的函数指针 typedef,类似的东西

namespace bpy = boost::python;
bpy::class_<Eigen::MatrixXd>("MatrixXd",
        "Variable-size double-precision matrix class",
        bpy::init<const Eigen::MatrixXd&>()
    )
        .def("__call__", static_cast<parop_signature>(&Eigen::MatrixXd::operator()))
        // ...
;

问题是我无法弄清楚函数的正确签名是什么。 “操作上”它应该采用两个整数索引并返回一个 double 值。然而,

typedef const double& (Eigen::MatrixXd::*parop_signature)(int, int) const;

导致以下编译错误(Mac OS X,C++11 模式下的 clang++,Boost.Python V1.61):

address of overloaded function 'operator()' cannot be static_cast to type
      'const double &(MatrixXd::*)(int, int) const'
  ...static_cast<const double& (Eigen::MatrixXd::*)(int, int) const>(&Eigen::MatrixXd::operator())
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/eigen/current/Eigen/src/Core/DenseCoeffsBase.h:111:41: note: 
      candidate function
    EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
                                        ^
/usr/local/eigen/current/Eigen/src/Core/DenseCoeffsBase.h:171:5: note: 
      candidate function
    operator()(Index index) const
    ^
/usr/local/eigen/current/Eigen/src/Core/DenseCoeffsBase.h:334:5: note: 
      candidate function
    operator()(Index row, Index col)
    ^
/usr/local/eigen/current/Eigen/src/Core/DenseCoeffsBase.h:392:5: note: 
      candidate function
    operator()(Index index)

很公平,你会说:但我不知道如何告诉 Boost.Python CoeffReturnType 实际上是一个 double 在这里(或者可能是一个 const double&,谁知道呢?),并且 IndexType 将在一天结束时解析为普通的 int。我已经尝试了 typedef 的各种组合,有或没有 const 限定符。

甚至尝试像这样声明一个 C++11 风格的函数指针

auto eigen_indexfn = std::mem_fn<double(int,int)>(&Eigen::MatrixXd::operator());

,没有成功,我明白了

candidate template ignored: couldn't infer template argument '_Tp'
mem_fn(_Rp _Tp::* __pm)
^

有没有人已经经历过这个并且可以为我提供正确的签名,说明所有意图和目的应该像“double Eigen::MatrixXd::operator(int, int)”?任何提示将不胜感激。

最佳答案

似乎错误源于 Eigen::Index 不是 int 而是默认为 ptrdiff_t。仅仅因为 int 可以隐式转换为 Eigen::Index 并不意味着您可以将需要 Eigen::Index 的函数指针转换为需要 int 的函数指针。如果可能的话,您最终会在堆栈中传递错误大小的整数。

附录:如果您真的更喜欢 int 而不是 ptrdiff_t,您可以在包含 Eigen 之前将 EIGEN_DEFAULT_DENSE_INDEX_TYPE 定义为 int , as documented here ,请注意这会破坏 ABI 兼容性。

关于c++ - 用 Boost.Python 包装 Eigen 的 operator()() 时的重载分辨率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39685899/

相关文章:

c++ - 如何使用 Qt 减少小部件和窗口大小之间的距离?

C++根据其模板定义一个类成员类型

c++11 - 将 nullptr 解引用到 lambda 函数是否是未定义的行为?

c++ - 试图理解 C++ 中的线程

c++ - boost::Eigen::MatrixXf 的无锁队列

c++ - 为什么 '&' 会改变对象的行为?

c++ - atomic<int>::fetch_add 的成本与 __sync_fetch_and_add

cmake - 为 CMake 查找包 Eigen3

c++ - 如何按 block 初始化 "Eigen"- 矩阵?

c++ - Gstreamer - 将命令行 gst-launch 转换为 C 代码