gpt4 book ai didi

c++ - 在不知道实际内部数据类型的情况下返回给定 SEXP 的子集

转载 作者:行者123 更新时间:2023-11-27 23:36:20 25 4
gpt4 key购买 nike

我正在写一个 R package to provide debug helper functions gdb 打印 RSEXPRcpp 数据类型的变量值。

C/C++ 是一种强类型语言,但我想避免查询 SEXP 的内部数据类型并使用一堆 if 进行硬编码调度.

我如何通过这样的函数签名使用索引范围实现通用子集函数:

SEXP dbg_subset(SEXP x, R_xlen_t index_from, R_xlen_t index_to);

一个可能的解决方案是为每个可能的签名编写上述函数,例如。对于 INTSXPLGLSXPSTRSXP...但我很懒 ;-)

注意:我不能使用 C++ 模板,因为链接器只会为我的 C++ 代码(与“正在调试的库”中的不同)和 gdb 中使用的数据类型创建模板实例没有编译器可以在输入 C++ 表达式以查询变量时“即时”创建缺少的模板实例。

编辑:参见this answer (但它基于我想避免的模板):

最佳答案

您可以将 C++ 模板与 RCPP_RETURN_VECTOR 一起使用宏。这个宏将确保为所有(?)R 数据类型实例化模板:

#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]

template <int RTYPE>
Rcpp::Vector<RTYPE> debug_subset_impl(Rcpp::Vector<RTYPE> x,
R_xlen_t index_from,
R_xlen_t index_to){
// range [index_from, index_to)
Rcpp::Vector<RTYPE> subset(index_to - index_from);
std::copy(x.cbegin() + index_from, x.cbegin() + index_to, subset.begin());
// special case for factors == INTSXP with "class" and "levels" attribute
if (x.hasAttribute("levels")){
subset.attr("class") = x.attr("class");
subset.attr("levels") = x.attr("levels");
}
return subset;
}


// [[Rcpp::export]]
SEXP dbg_subset(SEXP x, R_xlen_t index_from, R_xlen_t index_to){
// 1-based -> 0-based
RCPP_RETURN_VECTOR(debug_subset_impl, x, index_from - 1, index_to - 1);
}

/*** R
set.seed(42)
dbg_subset(1:100, 3, 6)
dbg_subset(runif(100), 3, 6)
dbg_subset(letters, 3, 6)
dbg_subset(as.factor(letters), 3, 6)
*/

输出:

> Rcpp::sourceCpp('58965423.cpp')

> set.seed(42)

> dbg_subset(1:100, 3, 6)
[1] 3 4 5

> dbg_subset(runif(100), 3, 6)
[1] 0.2861395 0.8304476 0.6417455

> dbg_subset(letters, 3, 6)
[1] "c" "d" "e"

> dbg_subset(as.factor(letters), 3, 6)
[1] c d e
Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z

关于c++ - 在不知道实际内部数据类型的情况下返回给定 SEXP 的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58965423/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com