我编写了以下Rcpp代码,该代码可以编译,但未给出预期的结果。
// [[Rcpp::export]]
RObject test_1 (Rcpp::NumericVector& x)
{
NumericVector x1;
if (x.size() < 5)
{
NumericVector x1(x.size()*3);
for (int ii = 0; ii < x.size(); ii++)
{
x1[ii] = sqrt(x[ii]);
}
}
else
{
NumericVector x1(x.size()*2);
for (int ii = 0; ii < x.size(); ii++)
{
x1[ii] = sqrt(x[ii]);
}
}
return x1;
}
Run Code Online (Sandbox Code Playgroud)
x1,返回向量在if语句外部声明,其中返回向量x1的大小可以变化。但是,如果我声明NumericVector的大小,它将创建一个新对象,但是x1在空向量中返回。
以下代码有效:
// [[Rcpp::export]]
RObject test (const Rcpp::NumericVector& x)
{
NumericVector x1;
if (x.size() < 5)
{
NumericVector tmp(x.size()*3);
for (int ii = 0; ii < x.size(); ii++)
{
tmp[ii] = sqrt(x[ii]);
}
x1 = tmp;
}
else
{
NumericVector tmp(x.size()*2);
for (int ii = 0; ii < x.size(); ii++)
{
tmp[ii] = sqrt(x[ii]);
}
x1 = tmp;
}
return x1;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我声明了临时numericvector,然后将x1设置为该vector。
我前一阵子这样做,并且知道有一种方法可以在将NumericVector声明为特定大小后将其设置为特定大小,我只是不记得怎么做。
编辑:编辑了代码和问题,以显示在if语句之前如何不知道返回向量的大小。
您可以使用以下样式:
NumericVector x;
if (foo)
x = NumericVector(1);
else
x = NumericVector(2);
Run Code Online (Sandbox Code Playgroud)
甚至(如果要避免对生成的向量进行零初始化)
x = static_cast<NumericVector>(no_init(size));
Run Code Online (Sandbox Code Playgroud)
请注意,当您写
NumericVector x;
if (foo)
NumericVector x(1);
Run Code Online (Sandbox Code Playgroud)
您实际上正在创建两个 NumericVector名为的对象x-一个位于顶级范围内,而另一个位于该if语句范围内。
也就是说,值得理解的是,当你写
NumericVector x;
Run Code Online (Sandbox Code Playgroud)
您实际上是在创建一个对象,而不仅仅是声明一个对象(仅适用于内置类型,例如int)。因此,当您编写时NumericVector x,x实际上是由零参数NumericVector构造函数默认构造的(它会创建长度为0的数字向量)