Rcpp和移动语义

5
我在C++中实现了一个算法,输出一个包含大量元素的数组。现在,我想在Rcpp中实现一个包装器,以便可以通过使用R来调用此函数。
我在Makevars文件中指定了以下设置:

PKG_CXXFLAGS = -std=c++11

这样我就可以使用C++11版本。
// [[Rcpp::export]]
NumericMatrix compute(int width, int height)
{
  vector<data_t> weights(width * height);
  compute_weights(weights);

  NumericMatrix mat(height, width);
  copy(begin(weights), end(weights), mat.begin());

  return mat;
}

如果NumericMatrix在函数返回时被移动,则上述包装函数仍然有效,否则将创建一个新对象。

Rcpp是否利用了移动语义?如果没有,是否有任何解决方法来避免构建副本?


我对rcpp一无所知,但是如果你需要一个解决方法,我相信它肯定不会以返回值的方式进行。 - David
3
在任何像样的编译器上都应该进行NRVO优化,无论是否使用移动语义。 - T.C.
1
尽管NRVO,移动语义不是Rcpp的一部分。它们是您类的一部分。您的NumericMatrix是否具有rvalue引用构造函数?如果是这样,任何符合标准的编译器都将调用它。 - SergeyA
1
@SergeyA NumericMatrix是一个Rcpp类,不是我的。这就是我所问的。 - Nick
@Nick,你应该有它的头文件可用,对吧?看一下。 - SergeyA
2
引用Romain在此处的评论:“Rcpp没有为Rcpp类实现移动语义。由编译器自动生成的移动构造函数或赋值运算符可能不会执行正确的操作。”另外,请注意,您可以指定属性// [[Rcpp::plugins(cpp11)]],作为编辑Makevars的较不侵入性的替代方法。 - nrussell
1个回答

0
上述的包装函数在返回NumericMatrix时仍然保持高效,否则将创建一个新对象。如果没有,是否有任何解决方法可以避免构建副本?
我认为只有浅拷贝是由复制构造函数创建的,因此不应该有任何拷贝。请参见Rcpp: How to ensure deep copy of a NumericMatrix?

这个例子也证实了这一点。

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::NumericVector allocate_the_vec(R_xlen_t n_ele){
  Rcpp::NumericVector out(n_ele);
  return out;
}

/*** R
# got 16 GB ram on my laptop. 3 x 7 is an issue but 2 x 7 is not
how_large <- as.integer(7 * 10^9 / 8)
the_large_vec_1 <- allocate_the_vec(how_large)
object.size(the_large_vec_1)
the_large_vec_2 <- allocate_the_vec(how_large)
*/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接