Hi Dirk, many thanks for your quick reply. Maybe something like the below could work? The different constructor specifications are defined in the list ClassName@constructors, but I coudln't find where R decides which of these functions to call.
Thanks again, Jelmer overloaded.func <- function( x1, x2 ) { f1 <- function( x1, x2 ) { cat( "f1\n" ) return( x1 + x2 ) } f2 <- function( x1, x2 ) { cat( "f2\n" ) return( nchar(x1) + nchar(x2) ) } f3 <- function( x1, x2 ) { cat( "f3\n" ) return( x1 + nchar(x2) ) } f4 <- function( x1, x2 ) { cat( "f4\n" ) return( x1 + x2 ) } # add different versions to list func.list <- list( f1, f2, f3, f4 ) # define argument types of f1, f2, f3 argstypes <- list( c( "numeric", "numeric" ), # input arguments of f1 c( "character", "character" ), # input arguments of f2 c( "numeric", "character" ), # input arguments of f3 c( "numeric", "integer" ) ) # input arguments of f4 # get types of input arguments supplied by user inputtypes <- c( class( x1 ), class( x2 ) ) # get index of function that agrees with these arguments findex <- which( sapply( argstypes, function(type) { all(inputtypes == type) } ) ) # if there is such a function evalute it, otherwise return error if( length( findex ) == 0 ) { stop(paste( inputtypes, sep=' ' )) } else { return( func.list[[ findex ]]( x1, x2 ) ) } } overloaded.func( 3, 3 ) # f1 overloaded.func( "test", "test" ) # f2 overloaded.func( 3, "test" ) # f3 overloaded.func( 2, 3L ) # f4 overloaded.func( "test", 3 ) # error On Fri, May 13, 2011 at 18:58, Dirk Eddelbuettel <e...@debian.org> wrote: > > 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@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 > _______________________________________________ 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