简体   繁体   English

在 if() 语句中使用 any() 时 Rcpp 禁止转换

[英]Rcpp forbidden conversion when using any() in an if() statement

I am trying to convert my R function to C++ using Rcpp, but I came around errors that I don't understand quite well.我正在尝试使用 Rcpp 将我的 R 函数转换为 C++,但是我遇到了一些我不太了解的错误。

The following code gives my R function, my (poor) attempt to translate it and some examples of uses at the end (testing that the two function return the same thing...)下面的代码给出了我的 R 函数,我的(可怜的)翻译它的尝试以及最后的一些使用示例(测试这两个函数返回相同的东西......)

My R Code function:我的 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)
}

My attempt to create the same function with Rcpp .我尝试使用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);
}

I receive the following error messages:我收到以下错误消息:

/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))

If the Rcpp function is implemented correctly, then the following should work:如果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))

What's wrong with my cpp code?我的 cpp 代码有什么问题?

The reason the code isn't translating correctly is due to how the any() Rcpp sugar implementation was created.代码不能正确翻译的原因是any() Rcpp 糖实现是如何创建的。 In particular, we have that:特别是,我们有:

The actual return type of any(X) is an instance of the SingleLogicalResult template class, but the functions is_true and is_false may be used to convert the return value to bool . any(X)的实际返回类型是SingleLogicalResult模板类的实例,但函数is_trueis_false可用于将返回值转换为bool

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

Therefore, the solution is to add .is_true() to the any() function call, eg !any(condition).is_true() .因此,解决方案是将.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);
}

Then, through testing we get:然后,通过测试我们得到:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM