1

私はRcpp::XPtr、Armadillo オブジェクト (たとえばarma::Mat、サポートされているデータ型の 1 つの行列である可能性があります) を持っている状況にあります。ここで、要素数を照会する関数を書きたいと思います。これまでに思いついたのは次のとおりです(bigstatsrに触発されました):

#define DISPATCH_DATA_TYPE(CALL)                               \
{                                                              \
  switch (data_type)                                           \
  {                                                            \
    case 1: CALL(unsigned short)                               \
    case 2: CALL(unsigned int)                                 \
    case 3: CALL(unsigned long)                                \
    case 4: CALL(short)                                        \
    case 5: CALL(int)                                          \
    case 6: CALL(long)                                         \
    case 7: CALL(float)                                        \
    case 8: CALL(double)                                       \
    default: throw Rcpp::exception("Unsupported data type.");  \
  }                                                            \
}

template <typename T>
arma::uword mat_length(SEXP mat)
{
  Rcpp::XPtr< arma::Mat<T> > p(mat);
  return p->n_elem;
}

#define MAT_LENGTH(TYPE) return mat_length<TYPE>(mat);

// [[Rcpp::export]]
arma::uword mat_length(SEXP mat, int data_type)
{
  DISPATCH_DATA_TYPE(MAT_LENGTH)
}

これを行うより良い方法はありますか?私はかなりの数の関数にこのパターンを使用していますが、冗長性が問題になっています。理想的には、(もちろん機能しません)のような単一の簡潔な関数が必要です

arma::uword mat_length(SEXP mat)
{
  Rcpp::XPtr<arma::Mat> p(mat);
  return p->n_elem;
}

XPtrRからCにそのようなものを渡す2つの関数+すべての単一インスタンスのマクロの代わりに.

おまけの質問: マクロベースのアプローチに明らかな問題はありますか? これはどういうわけか非効率的ですか、それとも将来的に問題を引き起こす可能性がありますか?

再現可能な例を作成するには、追加します

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

// [[Rcpp::export]]
SEXP setup_mat(arma::uword n_rows, arma::uword n_cols)
{
  arma::mat* res = new arma::mat(n_rows, n_cols);
  return Rcpp::XPtr<arma::mat>(res);
}

Rcpp::sourceCpp()Rのファイルで実行します。

4

1 に答える 1