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

Tama Ma pingnang at phys.ethz.ch
Wed Dec 21 23:09:00 CET 2011


Dear all,

	This is something I desire for a long time, but I do not have currently the time to do that. 
	Let me summarize my desire:
		1) 	Copy constructor
		2)	Rcpp module objects being wrapped so that they could become arguments in C++ functions.
	
	I must apologize that sometimes ago, I did say that I want to help the effort, but it's time issue. Hope that I could get some time soon.

	Thank you very much.

	Maybe Dirk or Romain could give me some more specific hint on which part of the source code should I look at, to solve this problem... I could try to help...

Best regards,
Tama Ma



On Dec 21, 2011, at 11:00 PM, Richard Downe wrote:

> 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> 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> 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
>>> 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
> 
> _______________________________________________
> 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


Best regards,
Tama Ma 
(+41 78 640 50 15)

pingnang at phys.ethz.ch
www.phys.ethz.ch/~pingnang

HIT K 31.3
Institut für Theoretische Physik
Wolfgang-Pauli-Strasse 27
ETH Hönggerberg
8093 Zürich
Switzerland

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


More information about the Rcpp-devel mailing list