返回 Rcpp::Vector<RTYPE> 元素的类模板 [英] Template for class returning elements of Rcpp::Vector<RTYPE>
问题描述
考虑以下完全不做任何事情的类:
Consider the following class that does absolutely nothing:
class MyNumVec
{
private:
const NumericVector& x;
public:
MyNumVec(const NumericVector& y) : x(y) {}
double operator[](int i) const { // here
return x[i];
}
operator NumericVector() const { return x; }
};
我想让它更通用并使用模板,以便我将使用任何 Vector<RTYPE>
而不是数字向量,但问题是由标记的行评论,因为我必须声明输出类型.我尝试使用 C++11 中的 auto
类型,但它不起作用('auto' return without trailing return type
").如何将其转换为使用任何类型的 Vector
的模板?
I would like to make it more general and use template for it so that I'll be working with any Vector<RTYPE>
instead of numeric vectors only, but the problem is the line marked by comment since I must declare output type. I tried using auto
type from C++11, but it doesn't work ("'auto' return without trailing return type
"). How can this be translated to template working with Vector
of any type?
推荐答案
如果你需要坚持 C++98,通常的习惯用法是使用一个整数模板参数来表示 不同的SEXPTYPE
s.在处理 Rcpp::*Vector
(或 Rcpp::*Matrix
)时,您通常只关心其中的 5 个:
If you need to stick to C++98, the usual idiom is to use an integer template parameter to represent the different SEXPTYPE
s. When dealing with Rcpp::*Vector
(or Rcpp::*Matrix
) you are typically only concerned with 5 of these:
# Integer Value SEXPTYPE R Vector Rcpp Vector
# 10 LGLSXP logical LogicalVector
# 13 INTSXP integer IntegerVector
# 14 REALSXP numeric NumericVector
# 15 CPLXSXP complex ComplexVector
# 16 STRSXP character CharacterVector
完成此操作后,Rcpp::traits
命名空间中有用于常用转换的标准元编程工具:
Having done this, there are standard metaprogramming tools for commonly needed transformations in the Rcpp::traits
namespace:
SEXPTYPE
-> POD¹ 类型:storage_type
Rcpp::traits::storage_type
->::type double
Rcpp::traits::storage_type
->::type int
- 等
SEXPTYPE
-> POD¹ type:storage_type
Rcpp::traits::storage_type<REALSXP>::type
->double
Rcpp::traits::storage_type<INTSXP>::type
->int
- etc.
Rcpp::traits::r_sexptype_traits
-> 14 (::rtype REALSXP
)Rcpp::traits::r_sexptype_traits
-> 13 (::rtype INTSXP
)- 等
Rcpp::traits::r_sexptype_traits<double>::rtype
-> 14 (REALSXP
)Rcpp::traits::r_sexptype_traits<int>::rtype
-> 13 (INTSXP
)- etc.
¹
storage_type
产生 SEXP
(特别是CHARSXP
),而技术上 一个 POD 类型,它与其他简单向量类型的不同之处在于它的原子单位是一个不透明的指针(一个SEXP
),而不是,例如一个const char*
或std::string
正如预期的那样.¹
storage_type<STRSXP>::type
yieldsSEXP
(specifically, aCHARSXP
), and while technically a POD type, it differs from the other simple vector types in that its atomic unit is an opaque pointer (aSEXP
), and not, e.g. aconst char*
orstd::string
as might be expected.一个无趣的例子,为了简洁使用
RCPP_RETURN_VECTOR
:An uninteresting example, using
RCPP_RETURN_VECTOR
for conciseness:#include <Rcpp.h> template <int RTYPE> class MyNumVec { public: typedef Rcpp::Vector<RTYPE> vec_t; typedef typename Rcpp::traits::storage_type<RTYPE>::type storage_t; private: const vec_t& x; public: MyNumVec(const vec_t& y) : x(y) {} storage_t operator[](int i) const { return x[i]; } operator vec_t() const { return x; } }; template <int RTYPE> Rcpp::Vector<RTYPE> get_first_elem_impl(const Rcpp::Vector<RTYPE>& vec) { MyNumVec<RTYPE> tmp(vec); return Rcpp::Vector<RTYPE>::create(tmp[0]); } // [[Rcpp::export]] Rcpp::RObject get_first_elem(Rcpp::RObject x) { RCPP_RETURN_VECTOR(get_first_elem_impl, x); }
<小时>
get_first_elem(c(TRUE, TRUE, FALSE, TRUE, FALSE)) # [1] TRUE get_first_elem(1L:5L) # [1] 1 get_first_elem(1:5 + 0.5) # [1] 1.5 get_first_elem(1:5 + 2i) # [1] 1+2i get_first_elem(letters[1:5]) # [1] "a"
这篇关于返回 Rcpp::Vector<RTYPE> 元素的类模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!