Thanks, this works for me. Jelmer
On Mon, May 16, 2011 at 10:33, Romain Francois <[email protected]> wrote: > There is a mechanism for dispatching to the appropriate constructor, but > this needs extra work from you on the C++ side. I'm currently not entirely > happy about it, and this might change in the future for something nicer. > > Some information about it was posted on this thread: > http://article.gmane.org/gmane.comp.lang.r.rcpp/929/match=constructors > > You essentially have to supply an extra function that decides if the > constructor is appropriate for the arguments that are passed in: > > So your example would become something like this: > > library('inline') > library('Rcpp') > > test_code <-' > using namespace Rcpp; > > class Uniform { > public: > Uniform(double min_, double max_) : min(min_), max(max_) {} > Uniform(double max_, std::string dummy_) : min(0.0), max(max_){ > Rprintf("%s\\n", dummy_.c_str()); > } > Uniform(double max_ ) : min(0.0), max(max_) {} > > NumericVector draw(int n) const { > RNGScope scope; > return runif( n, min, max ); > } > > double min, max; > }; > > double range( Uniform* w) { > return w->max - w->min; > } > > bool fun1( SEXP* args, int nargs){ > if( nargs != 2 ) return false ; > if( TYPEOF(args[1]) == STRSXP ) return false ; > return true ; > } > bool fun2( SEXP* args, int nargs){ > if( nargs != 2 ) return false ; > if( TYPEOF(args[1]) != STRSXP ) return false ; > return true ; > } > > RCPP_MODULE(unif_module) { > class_<Uniform>( "Uniform" ) > > .constructor<double,double>("", &fun1 ) > .constructor<double,std::string>("", &fun2) > .constructor<double>() > > .field( "min", &Uniform::min ) > .field( "max", &Uniform::max ) > > .method( "draw", &Uniform::draw ) > .method( "range", &range ) > ; > } > ' > > fx <- cxxfunction( signature(), "" , include = test_code, plugin = "Rcpp" ) > unif_module <- Module( "unif_module", getDynLib(fx) ) > Uniform <- unif_module$Uniform > > u1 <- new( Uniform, 0, 10 ) > u1$min > u1$max > u1$range() > u1$draw( 10L ) > > u2 <- new( Uniform, 10, "test" ) > u2$min > u2$max > u2$range() > u2$draw( 10L ) > > u3 <- new( Uniform, 10 ) > u3$min > u3$max > u3$range() > u3$draw( 10L ) > > > Romain > > > Le 13/05/11 16:35, Jelmer Ypma a écrit : >> >> Dear Rcpp-list, >> >> I'm trying to expose multiple constructors of a C++ class to R using >> modules. Here is an example of what I want to do based on the Uniform >> example >> >> ===Begin: example >> library('inline') >> library('Rcpp') >> >> test_code<-' >> using namespace Rcpp; >> >> class Uniform { >> public: >> Uniform(double min_, double max_) : min(min_), max(max_) {} >> Uniform(double max_, std::string dummy_) : min(0.0), max(max_) >> { Rprintf("%s\\n", dummy_.c_str()); } >> Uniform(double max_ ) : min(0.0), max(max_) {} >> >> NumericVector draw(int n) const { >> RNGScope scope; >> return runif( n, min, max ); >> } >> >> double min, max; >> }; >> >> double range( Uniform* w) { >> return w->max - w->min; >> } >> >> RCPP_MODULE(unif_module) { >> class_<Uniform>( "Uniform" ) >> >> .constructor<double,double>() >> .constructor<double,std::string>() >> .constructor<double>() >> >> .field( "min",&Uniform::min ) >> .field( "max",&Uniform::max ) >> >> .method( "draw",&Uniform::draw ) >> .method( "range",&range ) >> ; >> } >> ' >> >> fx<- cxxfunction( signature(), "" , include = test_code, plugin = "Rcpp" ) >> unif_module<- Module( "unif_module", getDynLib(fx) ) >> >> show( Uniform ) >> u1<- new( Uniform, 0, 10 ) >> u1$min >> u1$max >> u1$range() >> u1$draw( 10L ) >> >> u2<- new( Uniform, 10, "test" ) >> u2$min >> u2$max >> u2$range() >> u2$draw( 10L ) >> >> u3<- new( Uniform, 10 ) >> u3$min >> u3$max >> u3$range() >> u3$draw( 10L ) >> ===End: example >> >> Compilation works fine (on Windows using RTools, Rcpp_0.9.4.1, >> inline_0.3.8), but the R code cannot distinguish between two >> constructors with the same number of arguments, but with different >> types for the arguments and always calls Uniform(double, double). The >> output I get is as follows: >> >>> unif_module<- Module( "unif_module", getDynLib(fx) ) >> >>> show( Uniform ) >> >> C++ class 'Uniform'<02748CF0> >> Constructors: >> Uniform(double, double) >> Uniform(double, std::string) >> Uniform(double) >> >> Fields: >> double max >> double min >> >> Methods: >> Rcpp::NumericVector draw(int) const >> >> double range() >> >> >>> u1<- new( Uniform, 0, 10 ) >> >>> u1$min >> >> [1] 0 >> >>> u1$max >> >> [1] 10 >> >>> u1$range() >> >> [1] 10 >> >>> u1$draw( 10L ) >> >> [1] 6.330045 4.637002 6.507183 4.192280 9.560602 3.927548 4.399107 >> 2.332956 8.810553 3.864929 >> >>> u2<- new( Uniform, 10, "test" ) >> >> Error in new_CppObject_xp(fields$.module, fields$.pointer, ...) : >> not compatible with REALSXP >> >> >> Does anyone know of a workaround for this? >> >> Many thanks in advance! >> Jelmer >> _______________________________________________ >> Rcpp-devel mailing list >> [email protected] >> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel >> > > > -- > Romain Francois > Professional R Enthusiast > +33(0) 6 28 91 30 30 > http://romainfrancois.blog.free.fr > http://romain-francois.com > |- http://bit.ly/hdKhCy : Rcpp article in JSS > |- http://bit.ly/elZJRJ : Montpellier Comedie Club - Avril 2011 > `- http://bit.ly/fhqbRC : Rcpp workshop in Chicago on April 28th > > > _______________________________________________ Rcpp-devel mailing list [email protected] https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
