[Rcpp-devel] c++ class as argument in rcpp function (using modules)

Richard Downe richard-downe at uiowa.edu
Wed Dec 21 23:00:20 CET 2011


A slightly hackish, if effective, workaround I've used in this instance 
is to have "as<>()" convert a string argument to a class return value, 
thereby avoiding the metaphysics of creating a c++ class in R.

     template <> fusionProject::TCFAFunctor *as( SEXP rs ) {
         using fusionProject::TCFAFunctor;

         if (!Rf_isString( rs ))
             throw std::runtime_error("Invalid argument.  String 
expected!");

         std::string defName = as<std::string>( rs );
         TCFAFunctor *retptr;

         if (defName.compare("A")==0)
             retptr = new fusionProject::tcfaDefinitionA;
         // else if (defName.compare("B")==0)
         //     retptr = new fusionProject::tcfaDefinitionB;
         else if (defName.compare("C")==0)
             retptr = new fusionProject::tcfaDefinitionC;
         else
             throw std::runtime_error("Unrecognized TCFA definition 
label.");

         return retptr;
     }

This works, with the caveat that the c++ code receiving the return value 
is responsible for deleting the pointer.  Nonetheless,  the syntax feels 
suitably "R-ish" on the R side, and I get what I wanted on the c++ side.
--rd


On 12/21/2011 03:55 PM, Yasir Suhail wrote:
> Hi
>
> I looked up the previous thread "Creating pointers to objects and 
> wrapping them"from 
> http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-April/002170.html, 
> and it seems that providing a specialization of the wrap<>() function 
> can help us return classes. Perhaps similarly, one could provide a 
> specialization of the as<>() function for arguments? While wrap is 
> implemented with the Language("new" ... function, is there any example 
> of an as<>() specialization for custom classes? The vignette 
> (http://dirk.eddelbuettel.com/code/rcpp/Rcpp-extending.pdf) shows a 
> declaration for as, but no definitions.
>
> Thanks!
>
> Yasir
>
>
>
> On Wed, Dec 21, 2011 at 5:45 AM, <romain at r-enthusiasts.com 
> <mailto:romain at r-enthusiasts.com>> wrote:
>
>     Iirc, this is not implemented yet.
>
>     There is a chance we might add this feature in the future.
>
>     Cheers,
>
>     Romain
>
>
>
>     Le 21 déc. 2011 à 10:59, Yasir Suhail <yusuhail at gmail.com
>     <mailto:yusuhail at gmail.com>> a écrit :
>
>>     I need to pass a class as an argument in a function I am exposing
>>     to R. From the skeleton package module, let us say that I have
>>
>>     class World {
>>     public:
>>         World() : msg("hello"){}
>>         void set(std::string msg) { this->msg = msg; }
>>         std::string greet() { return msg; }
>>         void addMsg(World& w2) {
>>     msg = msg + w2.msg;
>>         }
>>     private:
>>         std::string msg;
>>     };
>>
>>     However, this gives errors of the sort
>>     /usr/local/lib/R/site-library/Rcpp/include/Rcpp/module/Module_generated_CppMethod.h:186:4:
>>     error: invalid initialization of non-const reference of type
>>     'World&' from an rvalue of type 'World'
>>     In file included from
>>     /usr/local/lib/R/site-library/Rcpp/include/RcppCommon.h:306:0,
>>                      from
>>     /usr/local/lib/R/site-library/Rcpp/include/Rcpp.h:27,
>>                      from rcpp_module.cpp:1:
>>     /usr/local/lib/R/site-library/Rcpp/include/Rcpp/traits/Exporter.h: In
>>     constructor 'Rcpp::traits::Exporter<T>::Exporter(SEXPREC*) [with
>>     T = World, SEXPREC* = SEXPREC*]':
>>     /usr/local/lib/R/site-library/Rcpp/include/Rcpp/as.h:51:51:  
>>     instantiated from 'T Rcpp::internal::as(SEXPREC*,
>>     Rcpp::traits::r_type_generic_tag) [with T = World, SEXPREC* =
>>     SEXPREC*]'
>>     /usr/local/lib/R/site-library/Rcpp/include/Rcpp/as.h:75:89:  
>>     instantiated from 'T Rcpp::as(SEXPREC*) [with T = World, SEXPREC*
>>     = SEXPREC*]'
>>     /usr/local/lib/R/site-library/Rcpp/include/Rcpp/module/Module_generated_CppMethod.h:186:4:
>>       instantiated from 'SEXPREC* Rcpp::CppMethod1<Class, void,
>>     U0>::operator()(Class*, SEXPREC**) [with Class = World, U0 =
>>     World&, SEXPREC* = SEXPREC*]'
>>     rcpp_module.cpp:86:1:   instantiated from here
>>     /usr/local/lib/R/site-library/Rcpp/include/Rcpp/traits/Exporter.h:31:37:
>>     error: no matching function for call to 'World::World(SEXPREC*&)'
>>     rcpp_module.cpp:30:5: note: candidates are: World::World()
>>     rcpp_module.cpp:28:13: note:                 World::World(const
>>     World&)
>>     make: *** [rcpp_module.o] Error 1
>>
>>     Looking at
>>     http://dirk.eddelbuettel.com/code/rcpp/Rcpp-extending.pdf, it
>>     seems that I can extend Rcpp::as to account for my classes, but I
>>     still have two questions:
>>     1. How do I define the constructor World(SEXP)? Is there a
>>     working example somewhere for a user defined C++ class?
>>     2. Can I also use pointers and pass-by-reference as these are
>>     more often used in real C++ code.
>>
>>     In short, I'd appreciate a way to pass my C++ classes (as the
>>     class and also by ref. or pointer) that have been exposed to R as
>>     arguments to exposed functions. How do I achieve that?
>>
>>     Thanks!
>>     _______________________________________________
>>     Rcpp-devel mailing list
>>     Rcpp-devel at lists.r-forge.r-project.org
>>     <mailto:Rcpp-devel at lists.r-forge.r-project.org>
>>     https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>
>
>
>
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20111221/e13b445f/attachment-0001.htm>


More information about the Rcpp-devel mailing list