This post is a version of the rcpp-cpp11-usage README from the R&D Rcpp collection of compiled-code examples. The repository holds the full, runnable source.
This small example R package demonstrates how to choose the C++ standard that a package is compiled against, pinning it through the CXX_STD field of a Makevars file so the build does not depend on the compiler’s default. It is one of the “R&D Rcpp” prototype packages, a collection of minimal examples for integrating compiled code with R.
The r11 R package provides an example of choosing the C++ standard that a package is compiled against. The standard is selected through the CXX_STD field of a Makevars file, so the package builds against a known language version regardless of the compiler’s default.
Usage
To install the package, you must first have a compiler on your system that is compatible with R. For help on obtaining a compiler consult either macOS or Windows guides.
With a compiler in hand, one can then install the package from GitHub by:
# install.packages("remotes")
remotes::install_github("coatless-rd-rcpp/rcpp-cpp11-usage")
library("r11")Implementation Details
Every C++ compiler has a default language standard, and R pins one for the packages it builds. That default has risen over time. When this example was first written it was C++98, and opting in to C++11 was the interesting step. Modern R requires at least C++11, made C++17 the default in R 4.3, and has since moved the default to C++20. The mechanism for choosing a standard has stayed the same throughout: set CXX_STD in Makevars. This package pins C++17 and uses a function from the C++ standard library’s <random> facilities, which have been available since C++11.
.
├── DESCRIPTION # Package metadata
├── NAMESPACE # Function and dependency registration
├── R # R functions
│ ├── RcppExports.R # Autogenerated R to C++ bindings by Rcpp
│ └── r11-package.r # Package documentation
├── README.md
├── man # Package documentation
│ ├── r11-package.Rd
│ └── runif_cpp.Rd
├── r11.Rproj
└── src # Compiled code
├── Makevars # Selects the C++ standard via CXX_STD
├── Makevars.win
├── RcppExports.cpp # Autogenerated R bindings
└── runif_cpp.cpp # C++ function using the <random> libraryThe C++ Function
The function in src/runif_cpp.cpp draws n values from a uniform distribution using std::mt19937_64 and std::uniform_real_distribution, both from the <random> header. These were introduced in C++11, so the package must be compiled against at least that standard.
#include <Rcpp.h>
#include <random>
// [[Rcpp::export]]
Rcpp::NumericVector runif_cpp(unsigned int n, double start = 0.0, double end = 1.0,
unsigned int seed = 183) {
Rcpp::NumericVector u(n);
std::mt19937_64 engine(seed); // Mersenne Twister engine
std::uniform_real_distribution<double> u_dist(start, end);
for (unsigned int i = 0; i < n; i++) {
u[i] = u_dist(engine);
}
return u;
}The exported function also carries //' roxygen comments (trimmed from the excerpt here) that Rcpp::compileAttributes() copies into R/RcppExports.R to generate the help page.
Selecting the Standard with Makevars
src/Makevars, and src/Makevars.win on Windows, set the CXX_STD variable that R reads when building the package. Naming a standard such as CXX11, CXX14, CXX17, or CXX20 causes R to pass the matching flag to the compiler.
# Select the C++ standard the package compiles against.
CXX_STD = CXX17Pinning a specific standard with CXX_STD makes the package build the same way regardless of the host R’s default. On current R, whose default is C++20, CXX_STD = CXX17 selects C++17 explicitly, and on older R it guarantees at least that standard. Raising it to CXX20 or CXX23 is how you would request a newer standard.
DESCRIPTION
A package can also request a standard through the SystemRequirements field of DESCRIPTION, for example SystemRequirements: C++17. That field-based approach is an alternative to the Makevars CXX_STD shown above, and this package uses the Makevars approach. Surfacing the C++ code with Rcpp requires Rcpp under both LinkingTo (for the headers used at compile time) and Imports (so it is available at run time).
LinkingTo:
Rcpp
Imports:
Rcpp (>= 1.0.12)Source
The full package source is available on GitHub, and the rendered package site can be browsed at rd-rcpp.thecoatlessprofessor.com/rcpp-cpp11-usage.