Search code examples
c++rrcpp

How to use struct vector as an input parameter in Rcpp


I need to supply a vector of structs to an Rcpp function. The cpp file is as below

#include <Rcpp.h>


using namespace Rcpp;

struct teststc{
  int y;
};


// [[Rcpp::export]]
void teststruct(std::vector<teststc>  ys){
  Rcpp::Rcout <<"test"<<std::endl;
}

When I compile this cpp file, it returns this error

error: no matching constructor for initialization of 'teststc'

I actually see some functions using similar input parameters. So, I don't know why mine doesn't work. Any help is greatly appreciated!


Solution

  • The problem is that you are trying to export a function to R that takes as an argument an object of type std::vector<teststc>. Such an object does not exist in R, so it cannot pass it to the C++ code.

    If you want to be able to pass an object to C++ from R and convert it into your own struct, then you must write the C++ code that will convert an R object to your struct. Rcpp makes this much easier, but it is not magical, and cannot automatically convert an R object into an arbitrary struct without being told how you would like this to happen. You would therefore need to write the C++ code to do this.

    For example, the following code will take an integer vector from R, convert it into a std::vector<teststc>, then print out the elements of that vector:

    #include <Rcpp.h>
    #include <vector>
    
    using namespace Rcpp;
    
    struct teststc {
      int y;
      teststc(int x) { this->y  = x;}
    };
    
    std::vector<teststc> make_testvec(IntegerVector iv) {
      std::vector<teststc> out;
      for(int i = 0; i < iv.size(); ++i) {
        out.push_back(teststc((int) iv[i]));
      }
      return(out);
    }
    
    // [[Rcpp::export]]
    void teststruct(IntegerVector ys) {
      std::vector<teststc> stc = make_testvec(ys);
      for(unsigned i = 0; i < stc.size(); ++i) {
       Rcout << stc[i].y << ' '; 
      }
      Rcpp::Rcout << std::endl;
    }
    

    So that back in R I can do:

    teststruct(1:5)
    #> 1 2 3 4 5