Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Context
Extending wrap
to custom classes has always been a struggle in Rcpp
, and led to the split between RcppCommon.h
and Rcpp.h
, the idea being that you load a “minimal” subset of Rcpp, declare your class, declare that you are going to provide a specialization of wrap
, load the rest of Rcpp
(the meat), and finally define your specialization.
Let’s consider this template class :
template <typename T> class MyType {} ;
it does nothing, I’m just using it to illustrate the point. Extending wrap
for such a template will allow us to write functions like this:
// [[Rcpp::export]] MyType<double> test(){ return MyType<double>() ; }
Attributes will generate code that uses wrap
internally. So all we have to do is write this special wrap
. The simplest way is for classes that have an operator SEXP
but for the purpose of this post, let’s just consider it does not and that we can’t make modifications to the class.
implement wrap with Rcpp
In Rcpp, here is what it takes to implement wrap
for it (according to the extending vignette).
// first include the minimal set of Rcpp functionality #include <RcppCommon.h> // declare our type template <typename T> class MyType {} ; // declare that we will later specialize wrap namespace Rcpp{ template <typename T> inline SEXP wrap( const MyType<T>& obj ) ; } // include the rest #include <Rcpp.h> // and finally define the overload namespace Rcpp{ template <typename T> inline SEXP wrap( const MyType<T>& obj ) { return IntegerVector::create( 1, 2 ) ; } }
This has been the basis for packages like RcppArmadillo
, etc … and it requires lots of care. The definition of our wrap
must be after we include Rcpp.h
because we need IntegerVector::create
, inclusion of Rcpp.h
so that all uses of wrap
know about our specialization, the declaration of our specialization must be after RcppCommon.h
because that’s where we declare the general wrap
.
That’s a lot to stomach.
implement wrap in Rcpp11
In Rcpp11
the RcppCommon.h
does not exist and specializing wrap
is simpler:
// include all Rcpp11 headers all at once #include <Rcpp.h> // our template class template <typename T> class MyType {} ; // specialization of the Wrapper template for it. namespace Rcpp{ template <typename T> struct Wrapper< MyType<T> > { static inline SEXP wrap( const MyType<T>& obj ){ return IntegerVector::create( 1, 2 ) ; } } ; }
All we have to do is write specializations of the Wrapper
template class. This is much simpler.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.