本文介绍了包中包含std::转换的RCPP代码的兼容性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在完成我一直在处理的一个包。所有的检查看起来都很好,而且在我的电脑上编译起来也没有问题。win-builder包也没有问题。作为进一步的检查,我尝试在一个同事的计算机上从源安装,但失败了。问题来自我取自a StackOverflow thread on vector powers in Rcpp的一个RCPP函数:

NumericVector vecpow(const NumericVector base, const NumericVector exp) {

  NumericVector out(base.size());

  std::transform(base.begin(), base.end(),
                 exp.begin(), out.begin(), ::pow);
  return out;
}

这对我来说可以很好地编译和工作,但在安装时会给我的同事抛出一个错误,涉及

error: no matching function function for call to 'transform'

candidate function template not viable: requires 4 arguments, but 5 were provided.
例如,我可以通过将原始代码中的::pow替换为pow来重现错误。我用的是Windows 8.1,我的同事用的是Mac。这位同事维护自己的包,其中包含大量的RCPP代码,通常在编译方面没有问题。

我认为这可能是编译器问题。原始线程有一些涉及C++11的替代代码(线程已经存在五年了),因此原则上,我可以使用替代代码替换有问题的代码。然而,由于我对此不是很有经验,这将是一次反复试验。我的问题是:出现这个错误有什么简单的原因吗?我如何修改我的代码,以确保该程序包可安装并可供大多数用户使用?

推荐答案

该错误是因为编译器无法将std::pow函数匹配为二进制操作(这可能是因为它至少有两个重载,并且编译器无法猜测浮点/双精度类型),从而导致以下注意事项:

然后退回到一元std::transform,其中只有4个参数推动第二个音符:

由于找不到可应用于指定参数的有效std::transform,编译停止。从pow切换到powf可解决此问题,因为编译器不必解决任何重载,但此更改可能会导致精度损失:

Rcpp::cppFunction("NumericVector vecpow(const NumericVector base, const NumericVector exp) {
  NumericVector out(base.size());
  std::transform(base.begin(), base.end(),
                 exp.begin(), out.begin(), ::powf);
    
  return out;
}
") -> pow
pow(1:5,5:1)
[1]  1 16 27 16  5

另一种解决方法是使用静态强制转换,即将::pow替换为static_cast<double(*)(double, double)>(::pow),以告知编译器使用pow

double重载

这篇关于包中包含std::转换的RCPP代码的兼容性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 20:48