Overload inherited methods in an Rcpp class

Viewed 75

I have two classes A, the parent and B, the child. B overloads a method from A. The problem is that the method getval is not overloaded when exposing class B in an RCPP module, despite explicitly exposing it again a second time with a pointer to B::getval.

Is it due to a bug in Rcpp, a limitation or something I just don't know yet?

class A
{
public:
    A(int val) : val(val) {}

        int getval()
        {
                Rcout << "I am A" << endl;
                return val;
        }

private:
    int val;
};

class B : public A
{
public:
        using A::A;

        int getval()
        {
                Rcout << "I am B" << endl;
                return A::getval();
        }
};

RCPP_MODULE(rg)
{
    using namespace Rcpp;

    class_<A>("A")
        .constructor<int>()
        .method("getval", &A::getval);

    class_<B>("B")
        .derives<A>("A")
        .constructor<int>()
        .method("getval", &B::getval);
}
1 Answers

If I use my basic example above (in the question) in a simple C++ program as follows:

int main()                                                                                                                                                                                   
{                                                                                                                                                                                            
    A a(42);                                                                                                                                                                                  
    B b(43);                                                                                                                                                                                  
                                                                                                                                                                                      
    cout << a.getval() << endl;                                                                                                              
    cout << b.getval() << endl;                                                                                            
}

the correct method will be used. However, with Rcpp, the parent class A must declare the method getval as virtual:

virtual int getval()

In fact, it's good to declare the same method in B as virtual too. In R, it will finally work as expected:

a <- A$new(42)
b <- B$new(43)

Then:

a$getval()
I am A
[1] 42

b$getval()
I am B
I am A
[1] 43

Note that the message I am A under I am B is expected because in my example I do an explicit call the A::getval.

Related