2015-02-04 2 views
1

У меня есть кусок кода C++, что я пытаюсь обернуть с помощью наддува питона, который выглядит примерно так:подталкивание питона и шаблоны

заголовочного файла:

template<class CatalogClass, class MemberClass> 
class MyIterator 
{ 
    public: 
     MyIterator(SomeOtherArg& arg); 

    private: 
     Blah<CatalogClass,MemberClass>* mIterator; 

каст файла:

template<class CatalogClass, class MemberClass> 
MyIterator<CatalogClass, MemberClass>::MyIterator(SomeOtherArg& arg) 
{ 
    mIterator = new Blah<CatalogClass,MemberClass>(arg); 
} 

подталкивания каст:

class_<MyIterator<CatalogClass,MemberClass>>("MyIterator", init<SomeOtherArg&>()) 
; 

Моя причина для параметризации заключается в том, что MyIterator может использоваться различными классами, и поэтому мне не нужно переписывать этот итератор для каждого класса, который происходит из CatalogClass/MemberClass. Тем не менее, я получаю сообщение об ошибке на компиляции/связывания, который говорит:

Undefined symbols for architecture x86_64: MyIterator<CatalogClass,MemberClass>::MyIterator(SomeOtherArg&): referenced from boost::python::objects::value_holder<MyIterator<CatalogClass, MemberClass> >::value_holder<boost::python::objects::reference_to_value<SomeOtherArg&> >(_object*, boost::python::objects::reference_to_value<SomeOtherArg&>) in Test.o 

Где еще ждет меня, чтобы определить это? Благодаря!

ответ

1

Вы должны помнить, что шаблонные классы фактически не существуют до тех пор, пока вы не специализируетесь на шаблоне, это означает, что, если вы не предварительно специализируете свой итератор, символы не экспортируются, поэтому ничего не нужно ссылаться. Вы должны предварительно выделить свой итератор для каждой комбинации типов, которые вы планируете использовать, а затем отдельно разоблачить каждую специализацию на Python.

Другим решением является type erasure. Вам нужно будет изменить свой итератор, чтобы иметь не шаблонный базовый класс. Часть вашего класса, требующая шаблонов, наследуется от вашей не шаблонной базы. Затем вы сможете обернуть базовый класс, но шаблонный материал будет недоступен в Python.

В общем, я стараюсь избегать шаблонов в общедоступном интерфейсе любой библиотеки, которую я создаю для внешнего потребления. Вы можете шаблонировать все, что хотите, в своей реализации, но ваш публичный интерфейс должен создавать фактические символы компоновщика.

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