Search code examples
c++11vectorrcpp

Convert Rcpp::List to C++ vector of vectors of const char*


I'm trying to build an Rcpp interface to an existing C++ library that uses const char* for strings. I think I need to use Rcpp::List to pass some output indices, which is a ragged 2D array of strings. But I am having trouble converting this to the C++ primitives required by the external function.

#include <Rcpp.h>

// Enable C++11 via this plugin (Rcpp 0.10.3 or later)
// [[Rcpp::plugins(cpp11)]]

// [[Rcpp::export]]
void test(Rcpp::List IndexList){

      // convert list to this
      const std::vector<std::vector<const char*>> Indexes;
      for (int i = 0; i < IndexList.size(); i++){
          Rcpp::StringVector temp = IndexList[i];
          std::vector<const char*> temp2;
          temp2.clear();
          for (int j = 0; j < temp.size(); j++){
            Rcpp::Rcout << temp[j];
            temp2.push_back(temp[j]);
          }
          Indexes.push_back(temp2);
      }
}

/*** R

test(list(c("a", "b"), c("cde")))

*/

The line Indexes.push_back(temp2); throws an error which ever way I try to build this object (which I need to pass to another function).

Line 19 passing 'const std::vector<std::vector<const char*> >' as 'this' argument of 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::vector<const char*>; _Alloc = std::allocator<std::vector<const char*> >; std::vector<_Tp, _Alloc>::value_type = std::vector<const char*>]' discards qualifiers [-fpermissive]

Solution

#include <Rcpp.h>

// Enable C++11 via this plugin (Rcpp 0.10.3 or later)
// [[Rcpp::plugins(cpp11)]]

// function that wants this data structure
void feedme(const std::vector<std::vector<const char *>> &Indexes){

    Rcpp::Rcout << " feedme ";
    for (unsigned i = 0; i < Indexes.size(); i++){
        for (unsigned j = 0; j < Indexes[i].size(); j++){
            Rcpp::Rcout << Indexes[i][j];
        }
    }

}

// [[Rcpp::export]]
void test(Rcpp::List IndexList){

      // convert list to this
    Rcpp::Rcout << " test ";
    std::vector<std::vector<const char*>> Indexes;
      for (int i = 0; i < IndexList.size(); i++){
          Rcpp::StringVector temp = IndexList[i];
          std::vector<const char*> temp2;
          temp2.clear();
          for (int j = 0; j < temp.size(); j++){
            Rcpp::Rcout << temp[j];
            temp2.push_back(temp[j]);
          }
          Indexes.push_back(temp2);
      }

      feedme(Indexes);

}


/*** R

test(list(c("a", "b"), c("cde")))

*/

Solution

  • You are declaring Indexes as const but try to change it later on:

          const std::vector<std::vector<const char*>> Indexes;
    //    ^^^^^
    // [...]      
              Indexes.push_back(temp2);
    

    Remove the const qualifier to get the code compiled.