@hadley : malheureusement, je n'ai pas de ressources spécifiques en tête pour vous aider à démarrer en C++. Je l'ai appris dans les livres de Scott Meyers (Effective C++, More effective C++, etc ...) mais ce ne sont pas vraiment ce qu'on pourrait appeler des introductions.
Nous utilisons presque exclusivement l'interface .Call pour appeler du code C++. La règle est assez simple :
- La fonction C++ doit retourner un objet R. Tous les objets R sont SEXP.
- La fonction C++ prend entre 0 et 65 objets R en entrée (à nouveau SEXP).
- il doit (pas vraiment, mais nous pouvons garder cela pour plus tard) être déclaré avec un lien C, soit avec extern "C" o el RcppExport que Rcpp définit.
Ainsi, une fonction .Call est déclarée comme ceci dans un fichier d'en-tête :
#include <Rcpp.h>
RcppExport SEXP foo( SEXP x1, SEXP x2 ) ;
et implémenté comme ceci dans un fichier .cpp :
SEXP foo( SEXP x1, SEXP x2 ){
...
}
Il n'y a pas grand-chose de plus à savoir sur l'API R pour utiliser Rcpp.
La plupart des gens ne veulent traiter que des vecteurs numériques dans Rcpp. Vous faites cela avec la classe NumericVector. Il existe plusieurs façons de créer un vecteur numérique :
A partir d'un objet existant que vous transmettez de R :
SEXP foo( SEXP x_) {
Rcpp::NumericVector x( x_ ) ;
...
}
avec des valeurs données en utilisant la fonction statique ::create :
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
) ;
D'une taille donnée :
Rcpp::NumericVector x( 10 ) ; // filled with 0.0
Rcpp::NumericVector x( 10, 2.0 ) ; // filled with 2.0
Ensuite, une fois que vous avez un vecteur, la chose la plus utile est d'en extraire un élément. Cela se fait à l'aide de l'opérateur[], avec une indexation basée sur 0. Ainsi, par exemple, l'addition des valeurs d'un vecteur numérique se fait comme suit :
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 ) ;
}
Mais avec le sucre Rcpp, nous pouvons faire cela de manière beaucoup plus agréable maintenant :
using namespace Rcpp ;
SEXP sum( SEXP x_ ){
NumericVector x(x_) ;
double res = sum( x ) ;
return wrap( res ) ;
}
Comme je l'ai déjà dit, tout dépend du type de code que vous voulez écrire. Regardez ce que les gens font dans les paquets qui reposent sur Rcpp, consultez les vignettes, les tests unitaires, revenez nous voir sur la liste de diffusion. Nous sommes toujours heureux de vous aider.