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, <rom...@r-enthusiasts.com <mailto:rom...@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 <yusuh...@gmail.com
    <mailto:yusuh...@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@lists.r-forge.r-project.org
    <mailto:Rcpp-devel@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@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@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to