如何制作一个cpp(Rcpp)函数,在输入类型错误时触发“有用”的错误消息?

问题描述 投票:0回答:1

考虑这个 cpp 函数

// [[Rcpp::export]]
int timesTwo(int x) {
  return x * 2;
}

如果我在此函数中输入错误类型的对象(例如“字符”),显然,它将无法工作并显示此错误消息

Error: Not compatible with requested type: [type=character; target=integer].

但是,我想让它提供更多信息,例如

Error in timesTwo(int x)
Error: Not compatible with requested type: [type=character; target=integer].

Error in the parameter x of timesTwo(int x)
Error: Not compatible with requested type: [type=character; target=integer].

我想知道如何在cpp中做到这一点?

c++ r error-handling rcpp
1个回答
0
投票

有两种明显的方法可以解决这个问题。第一个是通过 R 中的包装器调用 cpp 函数,该包装器提前进行类型检查。例如:

Rcpp::cppFunction('
  int times_two_cpp(int x) {
    return x * 2;
  }')

timesTwo <- function(x) {
  if(!is.integer(x)) stop("'x' should be an integer, not ", typeof(x))
  times_two_cpp(x)
}

测试,我们有:

timesTwo(5L)
#> [1] 10

timesTwo('hello')
#> Error in timesTwo("hello") : 'x' should be an integer, not character

第二个选项是允许您的 C++ 函数接受任何 R 对象,并在内部进行类型检查。这需要一些 R 内部知识

Rcpp::cppFunction('
  Rcpp::IntegerVector timestwo(SEXP x) {
    int x_type = TYPEOF(x);
    if(x_type != INTSXP) {
     Rcpp::stop("in the parameter x of timesTwo - x is not an integer");
    }
    Rcpp::IntegerVector result(x);
    return result * 2;
   }
')

导致

timestwo(5L)
#> [1] 10

timestwo('hello')
#> Error: in the parameter x of timesTwo - x is not an integer
© www.soinside.com 2019 - 2024. All rights reserved.