如果您需要堅持使用C++ 98,通常的習慣用法是使用整數模板參數來表示the different SEXPTYPE
s。當Rcpp::*Vector
(或Rcpp::*Matrix
)的交易,你通常只關心這些5:
# 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
命名空間:
SEXPTYPE
- >POD¹類型:storage_type
Rcpp::traits::storage_type<REALSXP>::type
- >double
Rcpp::traits::storage_type<INTSXP>::type
- >int
- 等
- POD¹型 - >
SEXPTYPE
:r_sexptype_traits
Rcpp::traits::r_sexptype_traits<double>::rtype
- > 14(REALSXP
)
Rcpp::traits::r_sexptype_traits<int>::rtype
- > 13(INTSXP
)
- 等。
¹storage_type<STRSXP>::type
產生SEXP
(具體地說,CHARSXP
),並且當技術上一個POD類型,它與其它簡單的矢量的類型,因爲它的原子單元是不透明的指針(一個SEXP
)不同,並且不,例如如預期的那樣,可以使用const char*
或std::string
。
一個無趣例如,使用RCPP_RETURN_VECTOR
爲了簡明:
#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"
作爲參考,常規方法來做到這在C++ 98是到模板上的基本類'SEXPTYPE'並使用'Rcpp :: traits :: storage_type'來確定原子類型。 [例如](https://gist.github.com/nathan-russell/a6c154ae18d2a5cc8dcc3af06da01ea6#file-vector-template-cpp)。 – nrussell
@nrussell你能寫出這個要點嗎?這是'auto'例子的一個可行的替代方案。我有點害怕它可能會在SO的混亂中迷失方向。 – coatless