Я пытаюсь использовать partial_sort
из библиотеки <algorithm>
в Cython, но я просто не могу найти правильный способ правильно его extern
.
Здесь моя неудачная попытка:
%%cython -f
cdef extern from "<algorithm>" namespace "std":
void partial_sort[RandomAccessIterator](RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last)
void partial_sort[RandomAccessIterator, Compare](RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp)
Сообщение об ошибке при использовании Cython 0.19.1:
Error compiling Cython file:
------------------------------------------------------------
...
cdef extern from "<algorithm>" namespace "std":
cdef cppclass RandomAccessIterator:
cppclass Compare
void partial_sort[RandomAccessIterator]
^
------------------------------------------------------------
/Users/richizy/.ipython/cython/_cython_magic_cf4fbe14563c3de19c8c3af3253a182e.pyx:5:46: Not allowed in a constant expression
Error compiling Cython file:
------------------------------------------------------------
...
cdef extern from "<algorithm>" namespace "std":
cdef cppclass RandomAccessIterator:
cppclass Compare
void partial_sort[RandomAccessIterator]
^
------------------------------------------------------------
/Users/richizy/.ipython/cython/_cython_magic_cf4fbe14563c3de19c8c3af3253a182e.pyx:5:46: Array dimension not integer
Error compiling Cython file:
------------------------------------------------------------
...
cdef extern from "<algorithm>" namespace "std":
cdef cppclass RandomAccessIterator:
cppclass Compare
void partial_sort[RandomAccessIterator]
^
------------------------------------------------------------
/Users/richizy/.ipython/cython/_cython_magic_cf4fbe14563c3de19c8c3af3253a182e.pyx:5:25: Array element type 'void' is incomplete
Сообщение об ошибке при использовании Cython 0.20.1:
CompileError: command 'gcc' failed with exit status 1
warning: .ipython/cython/_cython_magic_121a91d1fdd64d85c4b01e6540fd86d6.pyx:4:52: Function signature does not match previous declaration
Изменение: по состоянию на 2/22/14, для Cython 0.20.1
https://groups.google.com/forum/#!topic/cython-users/H4UEM6IlvpM
Правильно, Cython не поддерживает специализированные шаблоны по умолчанию (для функций или классов). Он также не поддерживает параметры шаблона без имени (без какого-либо взлома). У обоих есть недостающие функции, которые мы хотели бы получить когда-нибудь.
- Роберт
Кажется, что Cython не работает с шаблоном специализации. Следующий код работает для меня (Cython версии 0.20, Python 2.7.5, g++ (SUSE Linux) 4.8.1)
from libcpp.vector cimport vector
cdef extern from "<algorithm>" namespace "std":
void partial_sort[RandomAccessIterator](RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last)
# void partial_sort[RandomAccessIterator, Compare](RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp)
cpdef bla():
cdef vector[int] v
cdef int i = 0
cdef list res = []
v.push_back(4)
v.push_back(6)
v.push_back(2)
v.push_back(5)
partial_sort[vector[int].iterator](v.begin(), v.end(), v.end())
for i in v:
res.append(i)
return res
затем
>>> import bla
>>> bla.bla()
[2, 4, 5, 6]
Однако раскол строки прерывает код с помощью
bla.pyx:15:16: Wrong number of template arguments: expected 2, got 1
Вот обходной путь: вы объявляете различную специализацию функции шаблона под двумя разными именами:
cdef extern from "<algorithm>" namespace "std":
void partial_sort_1 "std::partial_sort"[RandomAccessIterator](RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last)
void partial_sort_2 "std::partial_sort"[RandomAccessIterator, Compare](RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp)
И тогда вы используете правильный, как в:
partial_sort_1[vector[int].iterator](v.begin(), v.end(), v.end())
Примечание. Я получил от Cython-Users, что это проблема с информацией, и что частичная специализация шаблона на Cython находится на их списке пожеланий на мгновение.