比较Rcpp中的两个值,而不强制转换为特定类型

Comparing two values in Rcpp without casting to specific type

本文关键字:转换 类型 Rcpp 两个 比较      更新时间:2023-10-16

我试图使用Rcpp比较c++中的两个通用R值。在c++中如何比较两个值而不将它们强制转换为特定类型?

解释我的问题的代码如下,

require("Rcpp")
require("inline")
src <- "return wrap(x1 == x2);"
fun <- cxxfunction(signature(x1 = "SEXP", x2 = "SEXP"), src, plugin = "Rcpp")
fun("a", "a")
to_cmp <- "a"
fun(to_cmp, to_cmp)

它现在得到了FALSETRUE,而我希望它得到TRUETRUE

因为我的目标是在c++中实现一个数据结构,所以我更喜欢潜在的用户定义的==方法。

<标题> 可能的方法

我尝试过的一种方法是,

要求("Rcpp")

src <- '
Language call("`==`", x1, x2);
return call.eval();
'
fun <- cxxfunction(signature(x1 = "SEXP", x2 = "SEXP"), src, plugin = "Rcpp")
fun("a", "a")
to_cmp <- "a"
fun(to_cmp, to_cmp)

然而,当我运行这个,我得到Error: could not find function "`==`"

使用通用SEXP输入对象标记是正确的。要做到这一点,除了TYPEOF()之外,还需要使用c++模板。前者使比较函数中的正确向量创建能够与Rcpp糖挂钩,后者使正确的检查和分派能够发生。

#include <Rcpp.h>
using namespace Rcpp;
template <int RTYPE>
Rcpp::LogicalVector compare_me(Rcpp::Vector<RTYPE> x, Rcpp::Vector<RTYPE> y) {
    return x == y;
}
// [[Rcpp::export]]
Rcpp::LogicalVector compare_objects(SEXP x, SEXP y) {
    if (TYPEOF(x) == TYPEOF(y)) {
        switch (TYPEOF(x)) {
            case INTSXP:
                return compare_me<INTSXP>(x, y);
            case REALSXP:
                return compare_me<REALSXP>(x, y);
            case STRSXP:
                return compare_me<STRSXP>(x, y);
            default:
                Rcpp::stop("Type not supported");
        }
    } else {
        Rcpp::stop("Objects are of different type");
    }
    // Never used, but necessary to avoid the compiler complaining
    // about a missing return statement
    return Rcpp::LogicalVector(); 
}

的例子:

to_cmp <- "a"
compare_objects(to_cmp, to_cmp)
输出:

[1] TRUE

同样,上面的代码用于Rcpp::sourceCpp()。我鼓励您从使用inline切换到使用Rcpp::cppFunction()进行函数定义,因为它允许您专注于计算和而不是设置。