代码之家  ›  专栏  ›  技术社区  ›  Chiel

重载运算符()在Cython中失败

  •  0
  • Chiel  · 技术社区  · 5 年前

    我试图用Python使用Cython来包装手写模板C++类。代码不编译,因为 operator() Cannot assign to or delete this . 如何使代码编译?

    我的 .pyx 文件是:

    # distutils: language = c++
    import cython
    import numpy as np
    cimport numpy as np
    
    cdef extern from "<array>" namespace "std":
        cdef cppclass Dim_array_2 "std::array<int, 2>":
            Dim_array_2() except+
            int& operator[](size_t)
    
    cdef extern from "Array.h":
        cdef cppclass Array_2 "Array<double>":
            Array_2() except +
            void set_dims(const Dim_array_2&) except +
            double& operator()(const Dim_array_2&)
    
    def print_index():
        cdef Dim_array_2 dims
        dims[0] = 3
        dims[1] = 5
        cdef Array_2 a
        a.set_dims(dims)
    
        cdef Dim_array_2 index
    
        counter = 0.
        for j in range(dims[1]):
            for i in range(dims[0]):
                index[0] = i+1
                index[1] = j+1
                a(index) = counter # This fails.
                counter += 1.
    
        index[0] = 2
        index[1] = 3
        print(a(index))
    

    相应C++的简化版本 Array.h 是:

    #include <array>
    #include <vector>
    
    template<typename TF>
    class Array
    {
        public:
            Array() {}
            void set_dims(const std::array<int,2>& dims)
            {
                data.resize(dims[0]*dims[1]);
                this->dims = dims;
            }
    
            TF& data operator()(const std::array<int, 2>& index)
            {
                return data[ (index[0]-1) + (index[1]-1)*dims[0] ];
            }
    
        private:
            std::vector<TF> data;
            std::array<int,2> dims;
    };
    

    完整的错误消息是:

    Error compiling Cython file:
    ------------------------------------------------------------
    ...
        counter = 0.
        for j in range(dims[1]):
            for i in range(dims[0]):
                index[0] = i+1
                index[1] = j+1
                a(index) = counter # This fails.
                ^
    ------------------------------------------------------------
    
    test.pyx:31:13: Cannot assign to or delete this
    
    0 回复  |  直到 5 年前
        1
  •  1
  •   DavidW    5 年前

    我想 operator[] 已经被特别的特殊情况下工作,所以事实上它工作在假设类似的情况下并不能告诉你多少。

    你可能不得不放弃“好的” array(index) = value 语法,并编写一个小的C++包装器函数,帮助你:

    cdef extern from "Array.h":
        """
        void setArrayValue(Array<double>& arr, const std::array<int, 2>& idx, double value) {
            arr(idx) = value;
        }
        """
        # ...
    

    (我使用Cython的DOCSONT语法来包括小的C/C++代码片段)。

    在你的密码里 setArrayValue(a, index, counter) 相反。