@hadley: infelizmente, não tenho recursos específicos em mente para ajudá-lo a começar a usar C ++. Peguei nos livros de Scott Meyers (Effective C ++, More Effective C ++, etc ...), mas estes não são realmente o que se poderia chamar de introdutórios.
Usamos quase exclusivamente a interface .Call para chamar o código C ++. A regra é bastante fácil:
- A função C ++ deve retornar um objeto R. Todos os objetos R são SEXP.
- A função C ++ leva entre 0 e 65 objetos R como entrada (novamente SEXP)
- deve (não realmente, mas podemos guardar isso para mais tarde) ser declarado com C de ligação, quer com extern "C" ou o RcppExport alias que define Rcpp.
Portanto, uma função .Call é declarada assim em algum arquivo de cabeçalho:
#include <Rcpp.h>
RcppExport SEXP foo( SEXP x1, SEXP x2 ) ;
e implementado assim em um arquivo .cpp:
SEXP foo( SEXP x1, SEXP x2 ){
...
}
Não há muito mais a saber sobre a API R para usar o Rcpp.
A maioria das pessoas deseja lidar apenas com vetores numéricos no Rcpp. Você faz isso com a classe NumericVector. Existem várias maneiras de criar um vetor numérico:
De um objeto existente que você passou de R:
SEXP foo( SEXP x_) {
Rcpp::NumericVector x( x_ ) ;
...
}
Com os valores fornecidos usando a função :: criar estática:
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
) ;
De um determinado tamanho:
Rcpp::NumericVector x( 10 ) ; // filled with 0.0
Rcpp::NumericVector x( 10, 2.0 ) ; // filled with 2.0
Então, uma vez que você tenha um vetor, a coisa mais útil é extrair um elemento dele. Isso é feito com o operador [], com indexação baseada em 0, então, por exemplo, somar valores de um vetor numérico é algo assim:
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 ) ;
}
Mas com açúcar Rcpp podemos fazer isso muito mais bem agora:
using namespace Rcpp ;
SEXP sum( SEXP x_ ){
NumericVector x(x_) ;
double res = sum( x ) ;
return wrap( res ) ;
}
Como eu disse antes, tudo depende de que tipo de código você deseja escrever. Veja o que as pessoas fazem em pacotes que dependem do Rcpp, verifique as vinhetas, os testes de unidade, volte para nós na lista de discussão. Nós estamos sempre felizes em ajudar.