可能有几种不同的方法来解决这个问题,但这里提供一种使用 std::transform
的选项:
#include <Rcpp.h>
using namespace Rcpp;
struct Functor {
std::string
operator()(const std::string& lhs, const internal::string_proxy<STRSXP>& rhs) const
{
return lhs + rhs;
}
};
CharacterVector paste2(CharacterVector lhs, CharacterVector rhs)
{
std::vector<std::string> res(lhs.begin(), lhs.end());
std::transform(
res.begin(), res.end(),
rhs.begin(), res.begin(),
Functor()
);
return wrap(res);
}
首先将左手表达式复制到一个std::vector<std::string>
中的原因是,internal::string_proxy<>
类提供了带有如下签名的operator+
。
std::string operator+(const std::string& x, const internal::string_proxy<STRSXP>& y)
相比于,例如。
operator+(const internal::string_proxy<STRSXP>& x, const internal::string_proxy<STRSXP>& y)
如果您的编译器支持C++11,那么可以更加简洁地实现此操作:
#include <Rcpp.h>
using namespace Rcpp;
CharacterVector paste3(CharacterVector lhs, CharacterVector rhs)
{
using proxy_t = internal::string_proxy<STRSXP>;
std::vector<std::string> res(lhs.begin(), lhs.end());
std::transform(res.begin(), res.end(), rhs.begin(), res.begin(),
[&](const std::string& x, const proxy_t& y) {
return x + y;
}
);
return wrap(res);
}
internal::string_proxy<STRSXP>&
与String
的关系以及为什么不能使用String
吗? - NoBackingDownstring_proxy
基本上是一个轻量级的包装类(即代理类),当单个元素在Vector
中被访问时返回。这种方法使得可以为原本将是CHARSXP
或const char*
(可能)的东西添加功能(例如多个构造函数、运算符重载等),而不实际存储(“拥有”)一个SEXP
本身。 - nrussellstring_proxy
仅仅持有给定CharacterVector
中特定元素的引用,这使得修改可以通过代理对象并影响父向量(例如通过Vector::operator[]
)进行传递。另一方面,String
是更完整的字符串类。而string_proxy
仅包含一个静态的std :: string缓冲区、一个索引和指向其父向量的指针,String
包含更多数据成员,因此它将需要比等效代理对象更多的内存。 - nrussellString
“拥有”其底层数据(即SEXP data
成员),而不是持有对CHARSXP
的引用,因此对String
的修改将仅影响该对象本身,而不会影响其他任何东西。请注意这个示例中两个对象的行为差异。 - nrussell