从NumericVector填充C++数组的更好的习惯用法

Ari*_*man 10 c++ r rcpp

Rcpp用来包装一个用C语言编写的算法(不是我)(没有STL,没有提升,没有任何东西,据我所知).你可以在这里看到实现的算法(我正在包装kmeans_w_03).因此,我numeric从R 传入一个向量,然后需要将其转换为double数组.

目前我正在逐个元素地循环并从"tother"中填充一个,如下所示:

SEXP testfn(SEXP weightvec, SEXP cluster_num_k){
    Rcpp::NumericVector weightR(weightvec) ;
    int point_num = weightR.size();
    double weight[point_num] ;
    for(int i = 0; i < point_num; ++i) {
      weight[i] = weightR[i];
    }
}
Run Code Online (Sandbox Code Playgroud)

但是使用单元素数字向量,我可以利用Rcpp的漂亮的as转换功能:

int cluster_num = Rcpp::as<int>(cluster_num_k);
Run Code Online (Sandbox Code Playgroud)

但是,为长度> 1的数字向量尝试类似的东西会导致崩溃或错误,具体取决于语法的确切变体:

double weight[point_num] = Rcpp::as<double>(weightvec);
Run Code Online (Sandbox Code Playgroud)

我不一定介意循环,但我是一个完全新手,并怀疑有更好的方法.我已经阅读了Rcpp介绍,hadley的wiki教程和RcppExamples,但还没有找到解决这个问题的任何内容,但这并不意味着我不会错过它.我读到的Doxygen Rcpp文档是as可以转换为STL向量而不是数组(但我很难读取这些文档,所以我怀疑我错了).如果是这样,我想我可以投射到一个向量,然后到一个数组....

所以我的问题是:是否有更好的(更少的代码行,更具表现力的代码,甚至可以避免内存分配)的方式将a转换NumericVectordouble[]

Dir*_*tel 8

阿里,在之前的回答中,约翰提出了一个很好的观点.为了扩展一点,这里有一些问题

  • 你正在处理一个过时的编码标准库,它想要一个double[]或者一个*double
  • 你想使用更好的编码标准并利用Rcpp.

好吧,不要害怕,我们有一个简单的解决方案.Instantantiate将Rcpp::NumericVector X(weightvec);像往常一样,然后将它传递给你的函数foo()(或其他)作为

foo(X.begin())
Run Code Online (Sandbox Code Playgroud)

它为您提供所需的double*,如果需要,X.size()还提供长度.因为你来自R,所以当你之后返回R时,你不需要担心范围和生命周期.

如果你需要更明确,我也使用了丑陋的&(X[0]).

此外,Rcpp::as<>()施法者也可以使用std::vector<double>,所以你可以这样做

std::vector<double> x = Rcpp::as<std::vector<double> >(weightvec);
Run Code Online (Sandbox Code Playgroud)

但除了转换为C++类型之外,它在这里没有任何收获.

最后,如果Josh或其他C顽固分子在附近,所有这一切都使用了这样一个事实:SEXP来自R 的你保证有连续的C指针,所以你也可以通过这个非常古老的学校REAL(weightvec).