неочакван резултат, повтарящ се върху boost::python vector_indexing_suite

Обвих успешно клас с име Composite. Този клас има следния метод:

std::vector<Composite*> Composite::getChildren();

Опитах се да обвия върнатия std::vector с помощта на vector_indexing_suite по този начин: [фрагмент]

typedef std::vector<Composite*> CompositeArray;

BOOST_PYTHON_MODULE(composite)
{   
    class_<CompositeArray>("CompositeArray")
        .def(vector_indexing_suite<CompositeArray, true>());


    class_<Composite>("Composite", init<>())
        ... more wrapper
        .def("getChildren", &Composite::getChildren)
        ... more wrapper
        ;
}

Сега всичко изглежда работи правилно и когато извикам метода getChildren() от python, той връща правилно опакован CompositeArray. Мога да направя например:

from composite import Composite
myComp = Composite()

myComp.addChild('childA')
myComp.addChild('childB')

len(myComp.getChildren())  #returns 2
myComp.getChildren()[0] # returns the first child of type Composite

Но когато се опитам да повторя CompositeArray, като по този начин:

for child in myComp.getChildren():
    # do something with child...

Получих това съобщение за грешка:

TypeError: No to_python (by-value) converter found for C++ type: class Composite * __ptr64

което за мен няма смисъл, като се има предвид, че достъпът по индекс работи перфектно! Заседнал съм в това... имате ли представа какво правя погрешно?

Благодаря ти.


person Dan Niero    schedule 02.07.2012    source източник
comment
class Composite * __ptr64 изглежда, че итераторът връща чист указател и boost::python се опитва да го копира като обвит обект на Python. Предполагам, че не сте предоставили нещо като class_<Composite*>(). Можете ли да покажете тип връщане на Composite::iterator::operator*()?   -  person elmo    schedule 02.07.2012
comment
Благодаря, elmo, но не трябва ли указател към Composite да се обработва от class_‹Composite›? Никога не съм виждал обвиване на указател, само типа... така че сега съм още по-объркан. И какво имаш предвид за Composite::iterator::operator*(), самият Composite е просто нормален клас и няма итератор...   -  person Dan Niero    schedule 02.07.2012
comment
О, пропуснах, че контейнерът се казва CompositeArray и наследява от std::vector. В този случай върнатата стойност на CompositeArray::iterator::operator*() ще бъде указател. Доста съм изненадан, че се компилира, защото ако се опитате да дефинирате функция Composite * some_function() с .def("some_function", &some_function), това ще ви даде грешка, че трябва да предоставите правила за връщане. Мисля, че в горния код трябва да направим същото.   -  person elmo    schedule 02.07.2012
comment
Точно така, elmo, имам други методи, обвити, които връщат указатели и наистина трябваше да посоча политика за връщане за тях. Така че въпросът може би сега: как мога да посоча правилата за връщане за опакования std::vector‹Composite*› (или CompositeArray, ако предпочитате)??   -  person Dan Niero    schedule 02.07.2012
comment
Вероятно бих копирал предоставената реализация за vector_indexing_suite и се рови около това. Или просто наследете от това и заменете get_item като първи опит.   -  person elmo    schedule 02.07.2012
comment
Наистина странното е, че достъпът по индекс работи без проблеми!   -  person Dan Niero    schedule 02.07.2012
comment
Добре, тогава следващата ми стъпка ще бъде да стартирам това под дебъгера и да спра на това хвърляне и да видя проследяването на стека, за да се опитам да разбера как ще стигнем до там. for x in X всъщност използва ли get_item в този случай. Въпреки че все още съм объркан защо това работи за индекси...   -  person elmo    schedule 02.07.2012


Отговори (1)


Опитвам

class_<Composite, Composite*>("Composite", init<>())

Вместо

class_<Composite>("Composite", init<>())
person Paul Omta    schedule 23.12.2013