additional remark : if operator SEXP() ; is added to class father, children1_t, and children2_t the solution with XPtr compiles but gives the same result as the solution with shared_ptr (i.e. slicing) R.
----- Mail original ----- De: "Robin Girard" <robin.gir...@mines-paristech.fr> À: rcpp-devel@lists.r-forge.r-project.org Cc: "Robin GIRARD" <robin.gir...@mines-paristech.fr> Envoyé: Mercredi 3 Avril 2013 18:43:32 Objet: Module with vector of a class with inheritance, how to avoid slicing I am still working on my vector of a class father with inheritance (polymorphic subclasses ?). I created an exemple below that works fine but I face the known problem of "slicing" as named here : http://stackoverflow.com/questions/10154977/c-vector-with-inheritance and fail to implement the proposed solution. I have 2 tried 2 things and ended up with 2 questions: Question 1 - I tryed the solution proposed in the link with make_shared and shared_ptr. I had to add PKG_CXXFLAGS=-g -std=c++0x since my MinGW compiler did not find any -std=c++11. I got no compilation error but when I run the code it slices my children class : > res=new("Rcpp_vector_Of_father") > res$push_back(new("Rcpp_father")) > res$push_back_children1_t(new("Rcpp_children1_t")) > res$WhoAmI(1) father > res$WhoAmI(0) father > > res[[1]]$WhoAmI() father > res[[0]]$WhoAmI() father Question 2 - I tryed a solution with XPtr (although I'm not sure how this works) and got the following error at the module compilation example_mod_consumption.cpp: In member function 'void vector_Of_father::push_back_children1_t(children1_t)': example_mod_consumption.cpp:80:53: error: no matching function for call to 'std::vector<Rcpp::XPtr<father> >::push_back(Rcpp::XPtr<children1_t>)' below are the code for the two approach and at the end the code of the module. -------------------- Solution with XPtr #include <Rcpp.h> using namespace std; using namespace Rcpp; class father ; class children1_t; class children2_t ; class vector_Of_father; RCPP_EXPOSED_CLASS(father) RCPP_EXPOSED_CLASS(children1_t) RCPP_EXPOSED_CLASS(children2_t) RCPP_EXPOSED_CLASS(vector_Of_father) class father { public: ~father(){}; father(){}; father(father const & x) {}; void WhoAmI() const{ Rcout<<"father"<<endl; }; }; class children1_t : public father { public: ~children1_t(){}; children1_t(){}; children1_t(children1_t const & x){}; void WhoAmI() const{ Rcout<<"son1"<<endl; }; }; class children2_t : public father { public: ~children2_t(){}; children2_t(){}; children2_t(children2_t const & x){}; void WhoAmI() const{ Rcout<<"son2"<<endl; }; }; class vector_Of_father { public: std::vector<XPtr<father> > MyfatherList_; //std::vector<shared_ptr<father> > MyfatherList_; ~vector_Of_father(){}; vector_Of_father() : MyfatherList_(){}; father vec_get( int i) { return(*(MyfatherList_.at(i))); }; void WhoAmI(int i) const { MyfatherList_[i]->WhoAmI(); }; int size(){ return(MyfatherList_.size()); }; void push_back(father func){ MyfatherList_.push_back(XPtr<father>(&func)); }; void push_back_children1_t(children1_t func){ MyfatherList_.push_back(XPtr<children1_t>(&func)); }; }; -------------------- Solution with make_shared and shared_ptr only the class vector_of_father is different also #include <memory> is added after Rcpp.h include. class vector_Of_father { public: std::vector<shared_ptr<father> > MyfatherList_; ~vector_Of_father(){}; vector_Of_father() : MyfatherList_(){}; father vec_get( int i) { return(*(MyfatherList_.at(i))); }; void WhoAmI(int i) const { MyfatherList_[i]->WhoAmI(); }; int size(){ return(MyfatherList_.size()); }; void push_back(father func){ MyfatherList_.push_back(make_shared<father>(func)); }; void push_back_children1_t(children1_t func){ MyfatherList_.push_back(make_shared<children1_t>(func)); }; }; -------------- the module code RCPP_MODULE(mod_example2){ using namespace Rcpp; class_<father>( "father" ) //constructors .constructor() .method("WhoAmI",&father::WhoAmI) ; class_<children1_t>( "children1_t" ) .derives<father>("father" ) //constructors .constructor() .method("WhoAmI",&children1_t::WhoAmI) ; class_<children2_t>( "children2_t" ) .derives<father>("father" ) //constructors .constructor() .method("WhoAmI",&children2_t::WhoAmI) ; class_<vector_Of_father>( "vector_Of_father") .constructor() // .constructor<int>() .method( "size", &vector_Of_father::size) // .method("capacity", &cplfunctionvec::capacity,"Return size of allocated storage capacity. Returns the size of the storage space currently allocated for the vector, expressed in terms of elements.") // .method( "max_size", &cplfunctionvec::max_size) .method( "WhoAmI",&vector_Of_father::WhoAmI ) //.method( "test",&vector_Of_father::test ) .method( "push_back", &vector_Of_father::push_back ) .method("push_back_children1_t",&vector_Of_father::push_back_children1_t) // .const_method( "at", &cplfunctionvec::at ) .method("[[",&vector_Of_father::vec_get) // .method("[[<-",&vector_Of_father::vec_set) ; } Dr. Girard Robin Chargé de Recherche MINES-ParisTech / Département Energétique et Procédés / PERSEE / Groupe ERSEI Centre Procédés, Energies Renouvelables et Systèmes Energétiques (PERSEE) Center for Processes, Renewables Energies and Energy Systems Renewable Energies & Smartgrids (ERSEI) 1 Rue Claude Daunesse - CS 10207 - F-06904 Sophia Antipolis Cedex Tel: +33.4.93.67.89.64 (~99), Fax: +33.4.93.95.75.35 e-mail : robin.gir...@mines-paristech.fr web page perso http://www.mines-paristech.fr/Services/Annuaire/&?id=8828 statoverflow : http://stats.stackexchange.com/users/223/robin-girard web page centre PERSEE : http://www.cep.mines-paristech.fr/ linkedin : http://www.linkedin.com/profile/view?id=14907272&trk=tab_pro Le lien vaut mieux que le bien. ________________________________________________________ CONFIDENTIALITY : This e-mail and any attachments are confidential and may be privileged. If you are not a named recipient, please notify the sender immediately and do not disclose the contents to another person, use it for any purpose or store or copy the information in any medium. CONFIDENTIALITE : Ce message et les éventuelles pièces attachées sontconfidentiels et peuvent être une communication protégée. Si vous n'êtes pas dans la liste des destinataires, veuillez informer l'expéditeur immédiatement et ne pas ouvrir ni divulguer le contenu à une tierce personne, ne pas l'utiliser pour quelque raison que ce soit, ne pas stocker ou copier l'information qu'il contient sur un quelconque support. _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel