Reputation: 471
I have the following very simple code that defines a class B that takes as a parameter a pointer to an object of class A.
The code works perfectly if I compile it as standalone C++, but I haven't been able to expose class B using Rcpp. I must be doing something wrong in the line .constructor<A>()
near the end. Have tried all the combinations of &, *, etc. and nothing works. I'm lost after many hours of trying. Any ideas are welcome.
#include <Rcpp.h>
using namespace Rcpp;
class A {
public:
A(int val_) { val = val_; }
int val;
};
class B {
public:
B(A& ptr_) { ptr = &ptr_; }
int getval() { return (this->ptr->val); }
A *ptr;
};
RCPP_MODULE(module_cpp) {
using namespace Rcpp;
class_<A>("A")
.constructor<int>()
.field("val", &A::val)
;
class_<B>("B")
.constructor<A>()
;
}
Upvotes: 3
Views: 225
Reputation: 26823
Let's try to be stubborn: Your constructor for B
expects a reference to an A
, so we should expose it as such, i.e. .constructor<A&>()
. Doing so I get the error
invalid user-defined conversion from ‘SEXP’ {aka ‘SEXPREC*’} to ‘A&’
Basically we want to create something that's callable within R (the constructor for B
), but we can only use SEXP
as type for the arguments. And currently it is unknown how to convert between SEXP
and A&
. This sort of conversion would be the task of Rcpp::as
(and Rcpp::wrap
for the reverse), which are covered in the Rcpp-extending vignette. For Rcpp Modules, we can take the shortcut provided by RCPP_EXPOSED_AS
and friends, c.f. section 2.2.11 in the Rcpp-modules vignette.
Here a complete example with added verification code:
#include <Rcpp.h>
using namespace Rcpp;
class A {
public:
A(int val_) { val = val_; }
int val;
};
class B {
public:
B(A& ptr_) { ptr = &ptr_; }
int getval() { return (this->ptr->val); }
A *ptr;
};
RCPP_EXPOSED_AS(A);
RCPP_MODULE(module_cpp) {
using namespace Rcpp;
class_<A>("A")
.constructor<int>()
.field("val", &A::val)
;
class_<B>("B")
.constructor<A&>()
.method("getVal", &B::getval)
;
}
/***R
a <- new(A, 42)
b <- new(B, a)
b$getVal()
*/
Output:
> Rcpp::sourceCpp('61898230.cpp')
> a <- new(A, 42)
> b <- new(B, a)
> b$getVal()
[1] 42
Upvotes: 6