Exposing class method with default parameter using Rcpp

Viewed 61

I am trying to expose a class with a method having default values for some of the parameters. Consider the following code snippet:

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

using namespace Rcpp;

class XYZ{
    public:
        List A;
    
    XYZ(List A_) {
        A = A_;
    }

    void show_elem(const int j = 0) {
        Rcpp::print(A[j]);
    }

    void print_elem(const int j) {
        Rcpp::print(A[j]);
    }
};


// [[Rcpp::export]]
void test_show_elem(List A) {
  
  XYZ xyz(A);
  
  xyz.show_elem();
}

RCPP_MODULE(test_xyz) {
      class_<XYZ>("XYZ")
      .constructor<List>()
      .field("A", &XYZ::A)
      .method("print_elem", &XYZ::print_elem)
      .method("show_elem", &XYZ::show_elem)
      ;
};

RCPP_EXPOSED_CLASS(XYZ);

/*** R
x = list("w","a", 4)
xyz = new(XYZ, x)
xyz$print_elem(1)
test_show_elem(x)
xyz$show_elem()
*/

The output is:

> xyz$print_elem(1)
[1] "a"

> test_show_elem(x)
[1] "w"

> xyz$show_elem()
Error in xyz$show_elem() : could not find valid method

This shows that show_elem() works fine from within C++, but is not recognized by R. It seems that a class method with a default parameter is not properly exposed to R. Am I missing something?

1 Answers

It works once you

  • change the signature to not have default value: void show_elem(const int j)
  • call with a value i.e. xyz$show_elem(2)

Adjusted code below:

class XYZ{
public:
  List A;

    XYZ(List A_) {
        A = A_;
    }

    void show_elem(const int j) {
        Rcpp::print(A[j]);
    }

    void print_elem(const int j) {
        Rcpp::print(A[j]);
    }
};

RCPP_MODULE(test_xyz) {
      class_<XYZ>("XYZ")
      .constructor<List>()
      .field("A", &XYZ::A)
      .method("print_elem", &XYZ::print_elem)
      .method("show_elem", &XYZ::show_elem)
        ;

};

RCPP_EXPOSED_CLASS(XYZ)

/*** R
x = list("w","a", 4)
xyz = new(XYZ, x)
xyz$print_elem(1)
xyz$show_elem(2)
*/

Edit I took another look at our existing Rcpp Modules documentation and you cannot have a default argument for a methods element. You can have default arguments for free functions though.

Related