[Rcpp-devel] Exposing constructors with same number of arguments with different types using Rcpp Modules
Jelmer Ypma
jelmerypma at gmail.com
Mon May 16 14:03:47 CEST 2011
Thanks, this works for me.
Jelmer
On Mon, May 16, 2011 at 10:33, Romain Francois <romain at r-enthusiasts.com> 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
>> Rcpp-devel at lists.r-forge.r-project.org
>> 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
>
>
>
More information about the Rcpp-devel
mailing list