问题
I'm puzzled as to how arguments are passed into a cppFunction when we use Rcpp. In particular, I wonder if someone can explain the result of the following code.
library(Rcpp)
cppFunction("void test(double &x, NumericVector y) {
x = 2016;
y[0] = 2016;
}")
a = 1L
b = 1L
c = 1
d = 1
test(a,b)
test(c,d)
cat(a,b,c,d) #this prints "1 1 1 2016"
回答1:
As stated before in other areas, Rcpp establishes convenient classes around R's SEXP
objects.
- For the first parameter, the
double
type does not have a defaultSEXP
object. This is because within R, there is no such thing as a scalar. Thus, new memory is allocate making the&
reference incompatible. Hence, the variable scope for the modification is limited to the function and there is never an update to the result. As a result, for both test cases, you will see1
. - For the second case, there is a mismatch between object classes. Within the first call object supplied is of type
integer
due to theL
appended on the end, which conflicts with the C++ function expected type ofnumeric
. The issue is resolved once theL
is dropped as the object is instantiated as anumeric
. Therefore, an intermediary memory location does not need to be created that is of the correct type to receive the value. Hence, the modification in the second case is able to propagate back to R.
e.g.
a = 1L
class(a)
# "integer"
a = 1
class(a)
# "numeric"
来源:https://stackoverflow.com/questions/41083921/how-arguments-are-passed-into-a-cppfunction