[Rcpp-devel] Passing template class as argument in Rcpp function
Iñaki Ucar
iucar at fedoraproject.org
Fri Mar 5 18:44:08 CET 2021
Excellent. Note that the clone method was required for my use case, but it
may be superfluous for yours.
Iñaki
El vie., 5 mar. 2021 17:15, Subhomoy Ghosh <subhomoy25 at gmail.com> escribió:
> Thanks, Iñaki! Your package gave me enough hints to create the following
> attempt which seemed to have worked.
>
> #include <RcppArmadillo.h>
>
> using namespace Rcpp;
> using namespace arma;
>
> // [[Rcpp::depends(RcppArmadillo)]]
>
> class Distribution {
>
> public:
> virtual Distribution* clone() {return (new Distribution(*this));}
> virtual ~Distribution() {}
>
> };
>
> template <typename T>
> class Uniform : public Distribution {
>
> public:
> virtual Uniform<T>* clone() {return (new Uniform<T>(*this));}
> Uniform(const T &max,int i_) :
> max(max), i(i_) {}
>
> ~Uniform(){};
>
> T max;
> int i;
> };
>
>
>
> // [[Rcpp::export]]
> XPtr<Distribution> getUniformParam( SEXP max,int i,int type) {
> // create pointer to an Uniform object and
> // wrap it as an external pointer for base class
> if(type==1) {
> return Rcpp::XPtr<Distribution> (new
> Uniform<double>(as<double>(max), i) );
> } else if(type==2) {
> return Rcpp::XPtr<Distribution> (new Uniform<int>(as<int>(max),
> i) );
>
> }
> // return the external pointer to the R side
> return Rcpp::XPtr<Distribution>(R_NilValue);
> }
>
>
>
> // [[Rcpp::export]]
> double test2(double z, XPtr<Distribution> xp, int type) {
>
> Distribution* d=xp->clone();
> double tt=1;
> // convert the base pointer to derived class pointer
> if(type==1){
> Uniform<double> *f = dynamic_cast<Uniform<double> *>(d);
> tt = z * f->max;
> } else if (type==2){
> Uniform<int> *f = dynamic_cast<Uniform<int> *>(d);
> tt =z * f->max;
> }
>
> return tt;
> }
>
> // R side
> xp<- getUniformParam(2.3,2,1)
> test2(2,xp,1)
>
>
> On Thu, Mar 4, 2021 at 2:58 PM Iñaki Ucar <iucar at fedoraproject.org> wrote:
>
>> On Thu, 4 Mar 2021 at 20:31, Subhomoy Ghosh <subhomoy25 at gmail.com> wrote:
>> >
>> > Thanks, for the solution. I tried what you suggested and it shows "no
>> matching constructor for initialization of 'Rcpp::XPtr<Distribution>'".
>> Below here is my attempt:
>> >
>> > class Distribution {
>> >
>> > public:
>> > template <typename T>
>> > class Uniform2 {
>>
>> This is a nested class, which makes little sense in this context.
>> Uniform2 should *inherit* from Distribution. Again, see my package as
>> an example, which does exactly what you want.
>>
>> --
>> Iñaki Úcar
>>
>
>
> --
> Subhomoy
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20210305/e78cbb37/attachment.html>
More information about the Rcpp-devel
mailing list