C++ 如何正确捕获Rcpp异常?

C++ 如何正确捕获Rcpp异常?,c++,r,rcpp,C++,R,Rcpp,我创建了一个如下所示的函数: #include <Rcpp.h> //[[Rcpp::export]] void fun(SEXP num = R_NilValue){ if(!Rf_isNull(num)){ try{ int NUM = Rcpp::as<int>(num); }catch(...){ Rcpp::stop(&qu

我创建了一个如下所示的函数:

#include <Rcpp.h>


//[[Rcpp::export]]
 void fun(SEXP num = R_NilValue){
        if(!Rf_isNull(num)){
            try{
                  int NUM = Rcpp::as<int>(num);
            }catch(...){
                 Rcpp::stop("Exception occured!");
            }
        }
    }

现在,调用
fun('a')
在这里也会导致崩溃,即使我的类型不匹配。

您的示例并不完整,因为您没有告诉我们如何构建和调用函数

“通常”你不需要做任何事情,因为R为你做的。最简单的例子:

R> cppFunction("int doubleMe(int x) { return x + x; }")
R> doubleMe(21)
[1] 42
R> doubleMe("this won't work")
Error in doubleMe("this won't work") : 
  Not compatible with requested type: [type=character; target=integer].
R> 
如果在详细模式下使用
cpp函数
sourceCpp()
,则会看到生成的代码。如果您遵循该代码(包括使用的
#define
),您将看到它已经为您包含了一个
try/catch
块,这就是我说您不需要做任何事情的原因

现在,您当然可以用
R CMD COMPILE
和朋友们(非常)古老的方法“手工”构建函数——我10多年前的旧演示文稿向您展示了如果您需要快速阅读,如何插入手动
try/catch
块来亲自尝试

简而言之,“内部”Rcpp代码确实会抛出异常,这就是为什么设置“外部”Rcpp代码来捕获异常的原因。它工作得非常好,经过多年的改进,解决了大多数在实现中可能存在操作系统依赖性的难题

编辑:这里展示了如何在Rcpp属性之前的几天“手工”编译。它包括一个
try/catch
块,我们当时总是(手动)包含该块

编辑2:感谢您编辑您的问题。如果使用
[[Rcpp::export]]
最简单的版本是

//[[Rcpp::export]]
void fun(int num) {
    // do nothing
}
显示期望的行为:

R> sourceCpp("~/git/stackoverflow/63049304/answer.cpp")
R> fun(2)
R> fun("lalala")
Error in fun("lalala") : 
  Not compatible with requested type: [type=character; target=integer].
R> 
编辑3上一次编辑中发布的示例甚至没有编译。 修复后,它的行为与往常一样

R> cppFunction('std::string fun(int imax=1234) { return("okay"); }')
R> fun("a")
Error in fun("a") : 
  Not compatible with requested type: [type=character; target=integer].
R> fun('a')
Error in fun("a") : 
  Not compatible with requested type: [type=character; target=integer].
R> 

谢谢你的回答,我已经更新了我的问题。此函数作为R包的一部分导出,包含此函数的文件已包含在Makevars中。正如您在提供的链接中所示,我尝试添加多个catch块,但是catch(…){}block应该捕获发生的任何异常。正如我试图解释的,Rcpp的代码生成已经为您添加了
try/catch
块。查看RCPP的
include/RCPP/macros/macros.h
中的宏
BEGIN\u RCPP
VOID\u END\u RCPP
。谢谢,我会仔细阅读它们。抱歉,我再次更新了我的问题,因为我希望参数的默认值为
null
,然后将它们转换为整数。(并非每个函数调用都需要传递所有参数)。这是一个不同的问题,您可以通过搜索
Rcpp::Nullable
找到现有答案。我(广泛地)回答了你的离题(事后看来,可以说是重点不太明确)问题。我认为你接受这个问题是公平的。做一些家庭作业,然后可能会问一个新问题,最好是一个新问题。好的,我已经将我的问题改为以前的编辑,并接受了问题的答案。谢谢你的努力。我使用了
void-fun(Nullable-num=R_-NilValue){…}
,但无法将其转换回
int
,并得到了此错误
error:从'Rcpp::Nullable到'int-fpermissive
的用户定义转换无效。我将阅读更多手册,寻找可能的解决方案。
R> cppFunction('std::string fun(int imax=1234) { return("okay"); }')
R> fun("a")
Error in fun("a") : 
  Not compatible with requested type: [type=character; target=integer].
R> fun('a')
Error in fun("a") : 
  Not compatible with requested type: [type=character; target=integer].
R>