首页 > 解决方案 > 在 if() 语句中使用 any() 时,Rcpp 禁止转换

问题描述

我正在尝试使用 Rcpp 将我的 R 函数转换为 C++,但我遇到了我不太了解的错误。

下面的代码给出了我的 R 函数,我(糟糕的)尝试翻译它以及最后的一些使用示例(测试两个函数返回相同的东西......)

我的 R 代码功能:

intersect_rectangles <- function(x_min, x_max, y_min, y_max) {
  rez <- list()
  rez$min <- pmax(x_min, y_min)
  rez$max <- pmin(x_max, y_max)

  if (any(rez$min > rez$max)) {
    return(list(NULL))
  }
  return(rez)
}

我尝试使用Rcpp创建相同的功能。

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
List Cpp_intersect_rectangles(NumericVector x_min,NumericVector  
x_max,NumericVector  y_min,NumericVector  y_max) {

  // Create a list :
  NumericVector min = pmax(x_min,y_min);
  NumericVector max = pmin(x_max,y_max);
  List L = List::create(R_NilValue);

  if (! any(min > max)) {
    L = List::create(Named("min") = min , _["max"] = max);
  }
  return(L);
}

我收到以下错误消息:

/Library/Frameworks/R.framework/Versions/3.5/Resources/library/Rcpp/include/Rcpp/sugar/logical/SingleLogicalResult.h:36:2: error: implicit instantiation of undefined template 'Rcpp::sugar::forbidden_conversion<false>'
        forbidden_conversion<x>{
        ^
/Library/Frameworks/R.framework/Versions/3.5/Resources/library/Rcpp/include/Rcpp/sugar/logical/SingleLogicalResult.h:74:40: note: in instantiation of template class 'Rcpp::sugar::conversion_to_bool_is_forbidden<false>' requested here
                conversion_to_bool_is_forbidden<!NA> x ;
                                                     ^
file637e53281965.cpp:13:9: note: in instantiation of member function 'Rcpp::sugar::SingleLogicalResult<true, Rcpp::sugar::Negate_SingleLogicalResult<true, Rcpp::sugar::Any<true, Rcpp::sugar::Comparator<14, Rcpp::sugar::greater<14>, true, Rcpp::Vector<14, PreserveStorage>, true, Rcpp::Vector<14, PreserveStorage> > > > >::operator bool' requested here
    if (! any(min > max))

如果正确实现了Rcpp函数,那么以下应该可以工作:

u = rep(0,4)
v = rep(1,4)
w = rep(0.3,4)
x = c(0.8,0.8,3,3)
all.equal(intersect_rectangles(u,v,w,x), Cpp_intersect_rectangles(u,v,w,x))
all.equal(intersect_rectangles(u,v,w,w), Cpp_intersect_rectangles(u,v,w,w))

我的 cpp 代码有什么问题?

标签: rrcpp

解决方案


代码翻译不正确的原因是any() Rcpp 糖实现的创建方式。特别是,我们有:

的实际返回类型是模板类any(X)的一个实例 ,但函数 和可用于将返回值转换为.SingleLogicalResultis_trueis_falsebool

根据https://thecoatlessprofessor.com/programming/unofficial-rcpp-api-documentation/#any

因此,解决方案是添加.is_true()any()函数调用中,例如!any(condition).is_true().

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
List Cpp_intersect_rectangles(NumericVector x_min, NumericVector x_max,
                              NumericVector y_min, NumericVector y_max) {

    // Create a list :
    NumericVector min = pmax(x_min, y_min);
    NumericVector max = pmin(x_max, y_max);
    List L = List::create(R_NilValue);


    if (! any(min > max).is_true()) {
                      // ^^^^^^^^^ Added
        L = List::create(Named("min") = min , _["max"] = max);
    }
    return(L);
}

然后,通过测试我们得到:

u = rep(0,4)
v = rep(1,4)
w = rep(0.3,4)
x = c(0.8,0.8,3,3)
all.equal(intersect_rectangles(u,v,w,x), Cpp_intersect_rectangles(u,v,w,x))
# [1] TRUE
all.equal(intersect_rectangles(u,v,w,w), Cpp_intersect_rectangles(u,v,w,w))
# [1] TRUE

推荐阅读