Сопряжение массива C++11 С Cython


Я привык строить программы на C++ и получать их в Cython, но здесь я пытаюсь получить C++ 11 array, и это определенно не работает.

Вот мой .pxd:

cdef extern from "<array>" namespace "std" nogil :
    cdef cppclass array[T, size_t]:
        ctypedef T value_type
        cppclass iterator:
            T& operator*()
            iterator operator++()
            iterator operator--()
            iterator operator+(size_t)
            iterator operator-(size_t)
        bint operator==(iterator)
        bint operator!=(iterator)
        bint operator<(iterator)
        bint operator>(iterator)
        bint operator<=(iterator)
        bint operator>=(iterator)
        T& operator[](size_t)
        array() except +
        array(array&) except +

Большая часть этого файла является адаптацией из "вектора.pxd", но я удалил распределитель, потому что c++11 array в нем не нуждается. Я использовал size_t в качестве второго аргумента шаблона, но я не уверен в этом.

Проблема в том, когда я делаю:

    from array11 cimport array
    cdef array[int, 5] test   

Я получаю при компиляции:

Неизвестный тип в шаблоне аргумент

Если я это сделаю:

    from array11 cimport array
    cdef array[int, 5] * test = new array[int, 5]()

Я получаю:

Новый оператор может быть применен только к классу C++

Есть какие-нибудь идеи о том, что я делаю неправильно?

Спасибо!

1 3

1 ответ:

Как обсуждалось в комментариях, проблема, с которой вы столкнулись, заключается в том, что Cython на самом деле не поддерживает аргументы шаблона без типов. Рабочий круг (хаки и, вероятно, хрупкий) - это обмануть Cython, думая, что он предоставляет аргумент шаблона типа:

cdef extern from "<array>" namespace "std" nogil :
    cdef cppclass two "2":
        pass

    cdef cppclass array[T, U]:
        T& operator[](size_t)
        # this is obviously very very cut down

def f():
    cdef array[int,two] x
    return x[0]+x[1]
Фокус в том, что если вы сделаете cdef cppclass name "somestring", то Cython просто слепо заменит somestring на name, который генерирует правильный код C++. Очевидно, что есть некоторые ограничения с этим подходом, но для простого использования это должно быть хорошо.