[Rcpp-devel] Exposing constructors with same number of arguments with different types using Rcpp Modules

Dirk Eddelbuettel edd at debian.org
Fri May 13 18:58:22 CEST 2011


Hi Jelmer,

On 13 May 2011 at 16:35, Jelmer Ypma wrote:
| 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

If I recall correctly, we have determined that this cannot work. It is one of
these 'obvious in hindsight' issue.  Recall that R does the dispatch, and R
cannot differentiate between  foo(double) and  foo(int)  as it is not typed.

So I think you will have to differentiate the constructors by name. Sorry
about that, but even Rcpp modules has its limits.

And I may of course be wrong too in which case Romain may come in and
clarify.

Hope this helps,  Dirk

| 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

-- 
Gauss once played himself in a zero-sum game and won $50.
                      -- #11 at http://www.gaussfacts.com


More information about the Rcpp-devel mailing list