I recently developed the R package rivr
for teaching open-channel hydraulics.
Solving unsteady open-channel flow problems is often computationally expensive,
and an interpreted language
like R is usually not the right choice for this sort of program. However, the
Rcpp package makes it really
easy to embed C++ in your package. This means you can get the best of both
worlds by seamlessly linking compiled code into your R package. There are some
pretty great references for how and when you should
use C++ in R, but I think the best way to include it in packages is via
Rcpp attributes—especially
since it plays nice with devtools
and roxygen2
.
Programming with the C++ library provided by Rcpp
looks a lot like
programming in R. Consider the following function, first implemented in R and
then equivalently in C++:
They look basically the same! The most obvious differences are that
(1) C++ functions and variables need to have their types explicitly defined,
(2) loops are defined slightly differently, (3) C++ lines need to end with a
semicolon, (4) you can use shortcuts like a *= b
instead of writing a = a*b
,
and (5) C++ comments use //
instead of #
. Otherwise a lot of things are the
same; if
and while
statements have similar syntax, you use curly braces
{}
to group logic blocks, and you use return
and break
statements to exit
out of functions and loops.
There are a few other important differences that can trip you up though, and
some of them are subtle. I’ve made a short list of things for R programmers to
keep in mind when writing C++ code with Rcpp
.
Vector and matrix indices start at 0, rather than 1.
Consider the following function, first written in R and then in C++.
Use parentheses to refer to matrix elements.
Indexing a vector in C++ uses square brackets []
(like R), but for matrices
you must use parentheses ()
. To select an entire row or column of a matrix,
use _
in C++ .
double quotes ""
are type string
, but single quotes ''
are type char
.
This one took me an embarrassingly long time to figure out. You can’t use
logical operators to directly compare a string
to a char
, so you need to
be consistent on both sides of the equality.
You can’t store a function in a variable in C++, but you can use pointers to pass functions.
Pointers allow you to point to specific locations in the program memory, which means you can induce side-effects like change the underlying value of a variable or reference a function. You can do a lot with pointers, but they can also get you in trouble.
Pointing to variables has slightly different syntax. I can’t really think of an equivalent operation in R!
Those were the main pitfalls I ran into as an R programmer learning C++. Hopefully these tips and references will let you hit the ground running.
Comments
Want to leave a comment? Visit this post's issue page on GitHub (you'll need a GitHub account).