Hi,I have a list of base classes in C++, I want to access them in Python as a list of their derived most classes.Is there a build in means to cater for this in Boost.Python?I've made an example the problem I ma facing:
// ------------------------------- Code ----------------------------------//#include<memory>#include<iostream>#include<vector>namespace boost { template<class T> T* get_pointer(std::shared_ptr<T>& p){ return p.get(); }}struct Vehicle{ virtual ~Vehicle(){} friend bool operator==(const Vehicle& lhs, const Vehicle& rhs) { return true; }};struct Boat: public Vehicle{virtual ~Boat(){}friend bool operator==(const Boat& lhs, const Boat& rhs) { return true; }char const* testBoatSpecificMethod() { return "Floating."; }};struct Truck: public Vehicle{virtual ~Truck(){}friend bool operator==(const Truck& lhs, const Truck& rhs) { return true; }char const* testTruckSpecificMethod() { return "Trucking."; }};class Garage{public:Garage() {};~Garage() {};char const* test() { std::string temp = "Vehicle List Size: " + std::to_string(m_VehicleList.size()); return temp.c_str(); }friend bool operator==(const Garage& lhs, const Garage& rhs) { return true; }std::vector<Vehicle>& vehicleList() { return m_VehicleList; }private:std::vector<Vehicle> m_VehicleList;};#include <boost/python.hpp>#include <boost/python/suite/indexing/vector_indexing_suite.hpp>BOOST_PYTHON_MODULE(garage_ext){using namespace boost::python;class_<Garage>("Garage").def("test", &Garage::test).def("vehicleList", &Garage::vehicleList, return_internal_reference<1>());class_<Vehicle,std::shared_ptr<Vehicle>>("Vehicle");class_<Boat,std::shared_ptr<Boat>,bases<Vehicle>>("Boat").def("testBoatSpecificMethod", &Boat::testBoatSpecificMethod);class_<Truck,std::shared_ptr<Truck>,bases<Vehicle>>("Truck").def("testTruckSpecificMethod", &Truck::testTruckSpecificMethod);implicitly_convertible<std::shared_ptr<Boat>,std::shared_ptr<Vehicle>>();implicitly_convertible<std::shared_ptr<Truck>,std::shared_ptr<Vehicle>>();class_<std::vector<Vehicle> >("stl_vector_Vehicle").def(vector_indexing_suite<std::vector<Vehicle> >());}// --------------------------- Test Script -------------------------------//import garage_extg = garage_ext.Garage()l = g.vehicleList()l.append(garage_ext.Boat())print "Expecting a Boat object:"print str(l[0])print g.vehicleList()[0].testBoatSpecificMethod()garage_ext.f2("Done.")
// ------------------------------ Output ---------------------------------//Expecting a Boat object<garage_ext.Vehicle object at 0x7fb17a3bfb50>Traceback (most recent call last):File "test_garage.py", line 7, in <module>print g.vehicleList()[0].testBoatSpecificMethod()AttributeError: 'Vehicle' object has no attribute 'testBoatSpecificMethod''Vehicle' object has no attribute 'testBoatSpecificMethod'Here I want Vehicle to be a Boat object.If there is not a build in or recommended/known Boost.Python means to handle this problem,I'm thinking of wrapping the list (Lots of accessors to be wrapped in my library.) with a get accessor returning a boost::python::list, storing the derived most types. Getting the derived most type possibly by calling overriden 'getAsDerivedClass' method. I would like to avoid this. I dislike having to add python usage specific methods to the library, for our design and vision values / reasons.Kind Regards,Christoff