From: Dieter V. <dva...@ax...> - 2009-08-27 13:29:23
|
Hi everyone, i've run into something that caught me by surprise in terms of implicit conversions and additional constructors provided through % extend. I experienced this issue in wrapping a C++ library to python. The basic issue is this: I have three classes A, B, C. A has only the default constructor A() B has a constructor B(const A &input) C has a constructor C(const B &input) and using %extend i add C(const A &input) i also have %implicitconv B; here's some python code: aobj = A() cobj = C(aobj) the last line first converts aobj to an instance of B, then uses the C(const B&) constructor. This is surprising since if C(const A&input) had been part of the original C class, then that's the constructor that would have been chosen. Is this the expected behavior? The reason this has come up is i have a bunch of custom container classes in my API, some of which can convert from one to another. I'm now trying to add additional constructors through %extend that take python containers (dict, set, list, tuple, or any iterable) so each class has an additional 'constructor' each accepting just a PyObject * as an argument. Obviously i could convert these to static factory methods in each class but the constructor would have been nicer syntax. thanks for any help/suggestions. Here's a header file containing the C++ classes: #include <iostream> class A { }; class B { public: B(const A &) { std::cout << "Constructing B from A" << std::endl; } }; class C { public: C() { std::cout << "Empty constructor" << std:: endl;} C(const B &) { std::cout << "Constructing C from B" << std::endl; } }; Here's the .i file: %module testsample2 %{ #include <iostream> #include "sample2.h" %} class A { }; %implicitconv B; class B { public: B(const A &); }; class C { public: C(const B &); }; %extend C { C(const A&) { std::cout << "Constructing C from A" << std::endl; return new C(); } }; And here's what i did to compile things: swig -c++ -python testsample2.i g++ -I/usr/include/python2.6 -c testsample2_wrap.cxx -o testsample2_wrap.o g++ -shared testsample2_wrap.o -o _testsample2.so In python execute the following: import testsample2 a = testsample2.A() c = testsample2.C(a) and i see this output: Constructing B from A Constructing B from A Constructing C from B |