2015-06-19 4 views
2

Из Cython Я использую C++ std:vector, и мне нужно удалить элемент. Для моего точного варианта использования все векторы имеют тип int. Я думал, что самый чистый способ сделать это - использовать std:remove и векторный метод erase. По какой-то причине, следующий код не удаляя элементы, как и ожидалось:Удаление элемента из std: vector в Cython

# distutils: language=c++ 
from libcpp.vector cimport vector 
cdef extern from "<algorithm>" namespace "std": 
    iter std_remove "std::remove" [iter, T](iter first, iter last, const T& val) 

cdef void remove(vector[int] vect, int elem): 
    vect.erase(std_remove[vector[int].iterator, int](vect.begin(), vect.end(), elem)) 

def blah(): 
    cdef vector[int] vect 
    cdef int i 
    for i in range(10): 
     vect.push_back(i) 
    for i in range(10): 
     print vect[i] 
     remove(vect, i) 
    return vect 

Когда я бегу print blah() я вижу:

0 
1 
... 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Другими словами, элементы не удаляются из вектора. Какую простую ошибку я делаю?

+0

Для начала написано 'std :: remove'. Во-вторых, ваша декларация 'remove' отличается между вашим первым и вторым блоками кода - какое определение вы фактически используете? – nneonneo

+0

Извините @nneonneo, я обновил свой код. Я нашел проблемы с объявлением ('::' является одним из них), но теперь удаление, похоже, не работает должным образом. Теперь этот вопрос отражает этот вопрос. –

+0

Чтобы ответить на ваш другой вопрос @nneonneo, я определил 'std_remove', который вызывается моей функцией' remove', которая предположительно фактически стирает элемент из вектора. –

ответ

3

Извлечение элемента из вектора на C++ чрезвычайно просто. Ваша комбинация удаления/удаления - for more complicated stuff.

Учитывая итератор it, то

v.erase(it) 

сотрет его (см pertinent vector doc).


Кстати, если вам нужно найти этот итератор, вы можете использовать find (от algorithm):

std::find(v.begin(), v.end(), value); 

Следовательно, чтобы удалить первое вхождение value, вы можете использовать

v.erase(std::find(v.begin(), v.end(), value)); 

PS На самом деле это не вопрос Китона. Это вопрос на C++, который возник в контексте Cython. Пожалуйста, подумайте о том, что нужно. Это поможет вам привлечь внимание к интересующему вас вопросу.

+1

Хорошо, спасибо за указание 'find' и стирание/удаление идиомы. Я смог обновить свой код, чтобы использовать find, но элементы все еще не удаляются: https://gist.github.com/bmabey/6b2ea582fd4c8a463af9 –

+0

Ничего, у меня не было '&', конечно. :) Еще раз спасибо. –

Смежные вопросы