Я не знаю, почему Cython создает код, который он производит - даже erase
в string.pxd нет, поэтому Cython должен выдавать ошибку.
Самый простойВ качестве обходного пути можно было бы ввести функцию erase
, которая обертывает std::string::erase
:
cdef extern from *:
"""
#include <string>
std::string &erase(std::string& s, size_t pos, size_t len){
return s.erase(pos, len);
}
"""
string& erase(string& s, size_t pos, size_t len)
# replace s.erase(i,1) -> erase(s,i,1)
Однако в C ++ стирание нулей не выполняется: это ошибка (см. @MS answer для исправления) и имеет O(n^2)
время выполнения (просто попробуйте его на b"\x00"*10**6
), правильный способ - использовать remove / erase-idiom :
%%cython --cplus
from libcpp.string cimport string
cdef extern from *:
"""
#include <string>
#include <algorithm>
void remove_nulls(std::string& s){
s.erase(std::remove(s.begin(), s.end(), 0), s.end());
}
"""
void remove_nulls(string& s)
cdef string my_func(string s):
remove_nulls(s)
return s
, который трудно использовать неправильно и является O(n)
.
Еще одно замечание, касающееся передачи `std :: string 'для значения.Подпись:
cdef string my_func(string s)
...
return s
означает, что есть две (ненужные) копии (с невозможностью RVO), может быть лучше избежать и передать s
по ссылке (по крайней мере, в cdef
-функциях):
def cy_func(string b):
remove_nulls(b) # no copying
return b