返回 Rcpp::Vector<RTYPE> 元素的类模板 [英] Template for class returning elements of Rcpp::Vector&lt;RTYPE&gt;

查看:40
本文介绍了返回 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,通常的习惯用法是使用一个整数模板参数来表示 不同的SEXPTYPEs.在处理 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 SEXPTYPEs. 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::rtype -> 14 (REALSXP)
      • Rcpp::traits::r_sexptype_traits::rtype -> 13 (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 yields SEXP (specifically, a CHARSXP), and while technically a POD type, it differs from the other simple vector types in that its atomic unit is an opaque pointer (a SEXP), and not, e.g. a const char* or std::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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆