3

There is a class I have to port to R. I have exposed it as a Rcpp module. However, I need to use that class outside of R also. I mean I want to test the class with google tests. In order to compile the tests the class must not use anything from Rcpp.

Unfortunately, the function creating an instance of the class has to have quite flexible argument list. I would like to use named arguments since there will be many arguments you may choose to specify. For that reasons I cannot declare constructor that would be of any use within R. It would be ok, if I could define a function that would perform as a factory method. I did.

RcppExport SEXP CEC__new(SEXP args);

RCPP_MODULE(cec) {
  using namespace Rcpp;
  class_<CEC>("cec")
    .method("test", &CEC::test)
    .method("loop", &CEC::loop)
    .method("singleLoop", &CEC::singleLoop)
    .method("entropy", &CEC::entropy)
    ;
}
setClass("cec", representation(pointer = "externalptr"))

setMethod("initialize", "cec", function(.Object, ...) {
    .Object@pointer <- .Call("CEC__new", ...)
    .Object
})

The problem is that I cannot call any methods of the instance I create. It looks like I have to define '$' for the class within R. I don't want do that. I would like to take advantage of the pretty, compact form Rcpp module offers. Can you suggest me how to solve this issue?

lord.didger
  • 1,357
  • 1
  • 17
  • 31

1 Answers1

2

You can use .factory for registering a free function as a constructor to your class, but in that case the function should return a pointer to a CEC. Something like this:

CEC* CEC__new(SEXP args);

RCPP_MODULE(cec) {
  using namespace Rcpp;
  class_<CEC>("cec")   
    .factory( CEC__new )
    .method("test", &CEC::test)
    .method("loop", &CEC::loop)
    .method("singleLoop", &CEC::singleLoop)
    .method("entropy", &CEC::entropy)
    ;
}

Or perhaps:

   .factory<SEXP>( CEC__new )
Romain Francois
  • 17,432
  • 3
  • 51
  • 77