@hadley: sfortunatamente, non ho in mente risorse specifiche per aiutarti a iniziare a usare C ++. L'ho preso dai libri di Scott Meyers (C ++ efficace, C ++ più efficace, ecc ...) ma questi non sono proprio ciò che si potrebbe chiamare introduttivo.
Usiamo quasi esclusivamente l'interfaccia .Call per chiamare il codice C ++. La regola è abbastanza semplice:
- La funzione C ++ deve restituire un oggetto R. Tutti gli oggetti R sono SEXP.
- La funzione C ++ accetta tra 0 e 65 oggetti R come input (di nuovo SEXP)
- si deve (non proprio, ma siamo in grado di salvare questo per dopo) essere dichiarata con collegamento C, sia con extern "C" o RcppExport alias che definisce Rcpp.
Quindi una funzione .Call viene dichiarata in questo modo in un file di intestazione:
#include <Rcpp.h>
RcppExport SEXP foo( SEXP x1, SEXP x2 ) ;
e implementato in questo modo in un file .cpp:
SEXP foo( SEXP x1, SEXP x2 ){
...
}
Non c'è molto altro da sapere sull'API R per utilizzare Rcpp.
La maggior parte delle persone vuole trattare solo con vettori numerici in Rcpp. Puoi farlo con la classe NumericVector. Esistono diversi modi per creare un vettore numerico:
Da un oggetto esistente che passi da R:
SEXP foo( SEXP x_) {
Rcpp::NumericVector x( x_ ) ;
...
}
Con valori dati utilizzando la funzione :: create static:
Rcpp::NumericVector x = Rcpp::NumericVector::create( 1.0, 2.0, 3.0 ) ;
Rcpp::NumericVector x = Rcpp::NumericVector::create(
_["a"] = 1.0,
_["b"] = 2.0,
_["c"] = 3
) ;
Di una determinata dimensione:
Rcpp::NumericVector x( 10 ) ; // filled with 0.0
Rcpp::NumericVector x( 10, 2.0 ) ; // filled with 2.0
Quindi, una volta che hai un vettore, la cosa più utile è estrarne un elemento. Questo viene fatto con l'operatore [], con l'indicizzazione basata su 0, quindi per esempio la somma dei valori di un vettore numerico è qualcosa del genere:
SEXP sum( SEXP x_ ){
Rcpp::NumericVector x(x_) ;
double res = 0.0 ;
for( int i=0; i<x.size(), i++){
res += x[i] ;
}
return Rcpp::wrap( res ) ;
}
Ma con lo zucchero Rcpp possiamo farlo molto più bene ora:
using namespace Rcpp ;
SEXP sum( SEXP x_ ){
NumericVector x(x_) ;
double res = sum( x ) ;
return wrap( res ) ;
}
Come ho detto prima, tutto dipende dal tipo di codice che vuoi scrivere. Guarda cosa fanno le persone nei pacchetti che si basano su Rcpp, controlla le vignette, gli unit test, torna da noi sulla mailing list. Siamo sempre felici di aiutarti.