Exposing inherited methods through the derived object using Rcpp modules [duplicate] - r

I got a problem when I try module with inheritance class. Basiclly, I can't compile this part.
RCPP_MODULE(PACE){
using namespace Rcpp;
class_<FPCAreg>("FPCAreg")
.constructor<List, List, double, double, int, bool, bool>()
.field("n", &FPCAreg::n)
;
}
Here FPCAreg is a inheritance class based on FPCA class, and "n" is defined in FPCA. No matter I use ".field("n", &FPCAreg::n)" or ".field("n", &FPCA::n)". When I use ".field("n", &FPCAreg::n)", the error message is "no matching function for call to blablabla", and for ".field("n", &FPCA::n)", that's same but different class name. Is there any suggestion? Thanks.

You can only declare fields and methods from the actual class. However, what you can do is expose the base class and the derived class, and hint the inheritance between them in derives.
Here is an example:
#include <Rcpp.h>
using namespace Rcpp;
class Base {
public:
Base(double x_) : x(x_){}
double x;
} ;
class Derived : public Base {
public:
Derived(int y_) : Base(2.0), y(y_){}
int y ;
} ;
RCPP_MODULE(PACE){
class_<Base>("Base")
.constructor<double>()
.field("x", &Base::x)
;
class_<Derived>("Derived")
.derives<Base>("Base")
.constructor<int>()
.field("y", &Derived::y)
;
}
I get this then from R:
> obj <- new(Derived, 10L)
> obj$y
[1] 10
> obj$x
[1] 2

Related

Rcpp override summary method for custom class

Suppose I have the following function:
List foo(List x)
{
x.attr("class") = "myOwnClass";
return(x);
}
I whant to override R summary method for foo function output. However the following R-style approach does not work:
List summary.myOwnClass(List x)
{
return(x)
}
During compilation I have a error which says that "expected initializer before '.' token".
Please help me to understand how to implement summary function override within Rcpp framework for my customly defined class.
Will be very greatfull for help!
I feel like this is likely a duplicate, but my initial search didn't pull one up. I add a quick answer for now, but if I later find one I'll delete this answer and propose a duplicate.
The way to solve this issue is to use the export tag to specify the function's R side name as summary.myOwnClass while using something else for the C++ side name; you can't have dots in the middle of a C++ function name (think about, e.g., how member functions are called -- it would be unworkable). So, we do the following
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List foo(List x)
{
x.attr("class") = "myOwnClass";
return(x);
}
// [[Rcpp::export(summary.myOwnClass)]]
List summary(List x)
{
return(x);
}
/*** R
l <- foo(1:3)
summary(l)
*/
Then we get the output we expect
> l <- foo(1:3)
> summary(l)
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
attr(,"class")
[1] "myOwnClass"

Argument attribute definition for Qore function implemented via QPP

I'd like to define a CPP __attribute__ for (Qore script) functions implemented in .qpp and preprocessed into plain .cpp.
Qore script class methods may be called from C++ side. In this case an empty function is implemented in QPP class definition and preprocessed in .cpp file. C++ compiler will raise warning messages during compilation. Solution is GNU attribute unused. Is somehow possible to define argument attributes in .qpp ?
MyClass::onAction(int arg0, reference arg1) {
}
Expanded in cpp as:
static QoreValue MyClass_onAction_HashBGD(QoreObject* self, MyClassObject *o, const QoreValueList* args, q_rt_flags_t rtflags, ExceptionSink* xsink)
Note: ScopeGuard.h contains #define UNUSED_VARIABLE __attribute__((unused)) but qpp syntax does not support "normal" C++ usage as argument prefix.
As there are also automatically expanded arguments seems function flag is to be implemented.
I believe this is already implemented; look at the implementation for [doc] in qpp.cpp; if you declare a parameter variable in a qpp file as [doc], it means that no C++ glue for that variable will be generated, and the parameter variable is for documentation only.
Example in QC_StreamWriter.qpp:
nothing StreamWriter::printf(string[doc] fmt, ...) {
sw->f_printf(args, xsink);
}
This generates the following C++ code:
// nothing StreamWriter::printf(string fmt, ...){}
static QoreValue StreamWriter_printf_VsVV(QoreObject* self, StreamWriter* sw, const QoreValueList* args, q_rt_flags_t rtflags, ExceptionSink* xsink) {
# 146 "QC_StreamWriter.qpp"
sw->printf(args, xsink);
return QoreValue();
}
I hope this helps!

'begin' was not declared in this scope

I have a class like that (I leave only the relevant part):
template<class T>
class MyList
{
public:
// ....
typename QList<T*>::iterator begin()
{
return list.begin();
}
typename QList<T*>::iterator end()
{
return list.end();
}
typename QList<T*>::iterator skip(int n)
{
auto ite = list.begin();
while(n --> 0)
++ite;
return ite;
}
QList<T*> list;
};
when I went to use the class:
MyList<Foo*> foo;
for(Foo* f : foo.skip(1)) {
I get this error:
'begin' was not declared in this scope
I remove skip() call, the loop works fine... I don't understand why. Why that and how do I fix this?
This is just how range-based for loops work in C++. In particular, when in a range expression the participant is a class type, in your case MyList, for the expression to be legitimate the class type must have defined members begin and end.
Member function MyList::skip returns an iterator to a QList<T*>. This iterator class doesn't define any begin and end members and the compiler renders this type (i.e., the iterator) not a legitimate participant for a range-based for loop expression while the class type MyList that has defined members begin and end renders legitimate.
More info on how a range-for loop works you can find here.

Function param default value std:vector initialization with Rcpp and C++11?

I am trying to write a C++/Rcpp function that has an optional argument whos default needs to be a vector of length 1 with a value of 0. The following does not compile properly:
cppFunction("std::vector<int> test(std::vector<int> out = {0}) {
return out;
}")
I get the following error:
Error in cppFunction("std::vector test(std::vector out =
{1}) {\n return out;\n}") : No function definition found In
addition: Warning messages: 1: No function found for Rcpp::export
attribute at fileee5f629605d7.cpp:5 2: In sourceCpp(code = code, env
= env, rebuild = rebuild, showOutput = showOutput, : No Rcpp::export attributes or RCPP_MODULE declarations found in source
What is the right way to do this?
This answer was posted on the Rcpp issue tracker. This is the desired result that I wanted just not with std::vector.
cppFunction("IntegerVector test(IntegerVector out = IntegerVector::create(0)) {
return out;
}")
You could wrap the underlying C++ function in an R function that uses a default value:
#include <Rcpp.h>
#include <vector>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
std::vector<int> cpp_test(const std::vector<int>& x)
{
return x;
}
/*** R
test <- function(X = c(0L))
{
cpp_test(X)
}
test()
test(c(1:5))
*/
which gives you
> Rcpp::sourceCpp('~/RcppFiles/cpp_test.cpp')
> test()
[1] 0
> test(c(1:5))
[1] 1 2 3 4 5
Currently the Rcpp package didn't support the exporting the default values. There are several packages to improve this (including Rcpp11), thought, I have a solution on Rcpp with RCPP_MODULES:
library("Rcpp")
cppFunction(plugins=c("cpp11"),'NumericVector test(std::vector<int> out) {
return wrap(out);
}
RCPP_MODULE(mod) {
function("test",&test,List::create( _["out"] = std::vector<int>({0})), "Simple description");
}', verbose=TRUE,rebuild=TRUE)
I change the return type, thought, it work even if you return std::vector<int>.
So, how this works: it just creates a documentation entry with the default value, third argument for RCPP_MODULES.
With just {0} my R crashes, so, it's necessary for me to put std::vector explicitly.

How to export Rcpp Class method with default arguments

I have a c++ class myClass which has a method foo(int x=0) and it has a parameter x with default value = 0. The c++ class could be exported to R by
RCPP_MODULE(my_module) {
class_< myClass >( "myClass" )
.constructor()
.method( "foo", &myClass::foo )
;
}
However, in R, I am not able to call myClass$foo without specifying the value of x.
I have to specify the value of x regardless the default value.
So my question is how to export Rcpp class method with default arguments. I tried to search it over the internet. The closest thing that I found was
using namespace Rcpp;
double norm( double x, double y ) { return sqrt( x*x + y*y );
}
RCPP_MODULE(mod_formals2) {
function("norm", &norm,
}
But it doesn't work in my case.
I had the same problem recently. After looking at the source file of rcpp handling the classes (~/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/module/class.h in my setup) I don't think that it is currently possible.
The best workaround I came up with was to create a wrapper in R to handle the default arguments.
Here is a full example demonstrating how to do it. I defined a simple function that accepts 3 arguments and outputs their sum. The second and third arguments are optional and set by default to 10 and 100.
mwe.cpp
#include <Rcpp.h>
class MWE {
public:
int sum_them(int mandatory_arg,
int optional_arg1,
int optional_arg2)
{
return (mandatory_arg+optional_arg1+optional_arg2);
}
};
RCPP_MODULE(mod_mwe) {
Rcpp::class_<MWE>( "MWE" )
.constructor()
.method("sum_them", &MWE::sum_them)
;
}
mwe.R
require('Rcpp')
# source the C++ code
sourceCpp('mwe.cpp')
# create an instance of the class:
my_mwe = new(MWE)
# assign a wrapper with default arguments to the instance:
assign('sum_them_wrapper',
function(mandatory_arg,
optional_arg1=10,
optional_arg2=100) {
return(my_mwe$sum_them(mandatory_arg, optional_arg1, optional_arg2))
},
envir = my_mwe
)
This outputs the expected result:
> my_mwe$sum_them_wrapper(3, optional_arg2=500)
[1] 513

Resources