Reputation: 1047
I have a piece of C++ code that I'm trying to wrap using boost python that looks roughly like this:
header file:
template<class CatalogClass, class MemberClass>
class MyIterator
{
public:
MyIterator(SomeOtherArg& arg);
private:
Blah<CatalogClass,MemberClass>* mIterator;
cpp file:
template<class CatalogClass, class MemberClass>
MyIterator<CatalogClass, MemberClass>::MyIterator(SomeOtherArg& arg)
{
mIterator = new Blah<CatalogClass,MemberClass>(arg);
}
Boost cpp:
class_<MyIterator<CatalogClass,MemberClass>>("MyIterator", init<SomeOtherArg&>())
;
My reason for the parameterization is so that the MyIterator can be used by a variety of classes, and thus, I don't need to rewrite this iterator for every class that derives from CatalogClass/MemberClass. However, I get an error on compilation/linking that says:
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
Where else is it expecting me to define this? Thanks!
Upvotes: 1
Views: 161
Reputation: 2137
You have to remember that templated classes don't actually exist until you specialize the template, this means that unless you pre-specialize your iterator no symbols are exported, so nothing to link to. You'd have to pre-specialize your iterator for every combination of types you plan on using and then separately expose each specialization to Python.
Another solution, is type erasure. You'd need to modify your iterator to have a non-templated base class. The portion of your class that requires templates would inherit from your non-templated base. You'll then be able to wrap the base class, but templated stuff would be inaccessible in Python.
In general, I try to avoid templates in the public interface of any library I create for external consumption. You can template all you want in your implementation, but your public interface has to produce actual linker symbols.
Upvotes: 1