如何使用可能为 NULL 的 Rcpp 字符串变量?
How to work with Rcpp strings variables which could be NULL?
我正在编写一个 R 包 + Rcpp 代码来与现有的 C++ 库一起工作。
在阅读了此处的教程后:https://gallery.rcpp.org/articles/optional-null-function-arguments/,我正在为如何使用 NULL 和字符串而苦苦挣扎。我很困惑,我无法从类型 Rcpp::Nullable<std::string>
转换为 std::string
(或等效地 Rcpp::Nullable<Rcpp::String>
转换为 Rcpp::String
在 C++ 中,我正在检查字符串(在 C++ 中)是否为空。如果字符串为空,我想return NULL。如果字符串(在 C++ 中)不为空,我想 return 字符串。
我的示例代码如下,为简单起见,修改了Rcpp.package.skeleton()
提供的函数rcpp_hello_world()
。我的目标是在 R 中 return 包含字符串或 NULL(如果字符串为空)的列表 (Rcpp::List)。
#include <Rcpp.h>
#include <string>
using namespace Rcpp;
// [[Rcpp::export]]
Rcpp::List rcpp_hello_world() {
// After calculations from external C++ library,
// the variable 'mystring' will either empty (i.e. "") or populated (e.g. "helloworld")
std::string mystring = "helloworld"; // string non-empty
Rcpp::Nullable<std::string> result_string = R_NilValue;
if (!mystring.empty()) {
std::string result_string(mystring);
}
Rcpp::List z = List::create(result_string);
return z ;
}
上面示例中的结果变量 result_string
应该是 NULL
或 "mystring"
---但是,上面的总是 return NULL
,这不是所需的行为。
然后我尝试查看是否可以在 Rcpp::Nullable<std::string>
和 std::string
之间转换类型:
std::string mystring = "helloworld";
Rcpp::Nullable<std::string> result_string = R_NilValue;
std::string result_string(mystring);
这会导致编译错误:
error: redefinition of 'result_string' with a different type: 'std::string'
(aka 'basic_string<char, char_traits<char>, allocator<char>>') vs 'Rcpp::Nullable<std::string>'
(aka 'Nullable<basic_string<char, char_traits<char>, allocator<char>>>')
我是否为此操作使用了错误的数据结构?或者如果值可能为 NULL,是否有更好的方法来处理字符串?
这是一个最基本的完整答案。在函数体中,您可以根据需要调整测试,这只是一个占位符示例。
代码
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List foo(Rcpp::NumericVector v) {
// we just us a random vector here to determine: if positive
// we inject a string, if negative NULL
const std::string mystring = "helloworld"; // if positive
int n = v.size();
Rcpp::List z(n);
for (int i=0; i<n; i++) {
if (v[i] < 0) {
z[i] = mystring;
} else {
z[i] = R_NilValue;
}
}
return z;
}
/*** R
set.seed(123)
foo(rnorm(3)))
set.seed(123456)
foo(rnorm(3))
*/
输出
> Rcpp::sourceCpp("~/git/Whosebug/70601602/answer.cpp")
> set.seed(123)
> foo(rnorm(3))
[[1]]
[1] "helloworld"
[[2]]
[1] "helloworld"
[[3]]
NULL
> set.seed(123456)
> foo(rnorm(3))
[[1]]
NULL
[[2]]
[1] "helloworld"
[[3]]
[1] "helloworld"
>
德克在上面是正确的:从根本上说,我的误解与对 Rcpp::Nullable
的混淆有关。
the helper class Nullable<> is only used for the function signature
以下最终对我有用:
Rcpp::List rcpp_hello_world() {
// After calculations from external C++ library,
// the variable 'mystring' will either empty (i.e. "") or populated (e.g. "helloworld")
std::string mystring = "helloworld"; // string non-empty
Rcpp::List z = Rcpp::List::create(Rcpp::Named("myresult") = nullptr);
if (mystring.empty()) {
z["myresult"] = R_NilValue;
} else {
z["myresult"] = mystring;
}
return z ;
}
我正在编写一个 R 包 + Rcpp 代码来与现有的 C++ 库一起工作。
在阅读了此处的教程后:https://gallery.rcpp.org/articles/optional-null-function-arguments/,我正在为如何使用 NULL 和字符串而苦苦挣扎。我很困惑,我无法从类型 Rcpp::Nullable<std::string>
转换为 std::string
(或等效地 Rcpp::Nullable<Rcpp::String>
转换为 Rcpp::String
在 C++ 中,我正在检查字符串(在 C++ 中)是否为空。如果字符串为空,我想return NULL。如果字符串(在 C++ 中)不为空,我想 return 字符串。
我的示例代码如下,为简单起见,修改了Rcpp.package.skeleton()
提供的函数rcpp_hello_world()
。我的目标是在 R 中 return 包含字符串或 NULL(如果字符串为空)的列表 (Rcpp::List)。
#include <Rcpp.h>
#include <string>
using namespace Rcpp;
// [[Rcpp::export]]
Rcpp::List rcpp_hello_world() {
// After calculations from external C++ library,
// the variable 'mystring' will either empty (i.e. "") or populated (e.g. "helloworld")
std::string mystring = "helloworld"; // string non-empty
Rcpp::Nullable<std::string> result_string = R_NilValue;
if (!mystring.empty()) {
std::string result_string(mystring);
}
Rcpp::List z = List::create(result_string);
return z ;
}
上面示例中的结果变量 result_string
应该是 NULL
或 "mystring"
---但是,上面的总是 return NULL
,这不是所需的行为。
然后我尝试查看是否可以在 Rcpp::Nullable<std::string>
和 std::string
之间转换类型:
std::string mystring = "helloworld";
Rcpp::Nullable<std::string> result_string = R_NilValue;
std::string result_string(mystring);
这会导致编译错误:
error: redefinition of 'result_string' with a different type: 'std::string'
(aka 'basic_string<char, char_traits<char>, allocator<char>>') vs 'Rcpp::Nullable<std::string>'
(aka 'Nullable<basic_string<char, char_traits<char>, allocator<char>>>')
我是否为此操作使用了错误的数据结构?或者如果值可能为 NULL,是否有更好的方法来处理字符串?
这是一个最基本的完整答案。在函数体中,您可以根据需要调整测试,这只是一个占位符示例。
代码
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List foo(Rcpp::NumericVector v) {
// we just us a random vector here to determine: if positive
// we inject a string, if negative NULL
const std::string mystring = "helloworld"; // if positive
int n = v.size();
Rcpp::List z(n);
for (int i=0; i<n; i++) {
if (v[i] < 0) {
z[i] = mystring;
} else {
z[i] = R_NilValue;
}
}
return z;
}
/*** R
set.seed(123)
foo(rnorm(3)))
set.seed(123456)
foo(rnorm(3))
*/
输出
> Rcpp::sourceCpp("~/git/Whosebug/70601602/answer.cpp")
> set.seed(123)
> foo(rnorm(3))
[[1]]
[1] "helloworld"
[[2]]
[1] "helloworld"
[[3]]
NULL
> set.seed(123456)
> foo(rnorm(3))
[[1]]
NULL
[[2]]
[1] "helloworld"
[[3]]
[1] "helloworld"
>
德克在上面是正确的:从根本上说,我的误解与对 Rcpp::Nullable
的混淆有关。
the helper class Nullable<> is only used for the function signature
以下最终对我有用:
Rcpp::List rcpp_hello_world() {
// After calculations from external C++ library,
// the variable 'mystring' will either empty (i.e. "") or populated (e.g. "helloworld")
std::string mystring = "helloworld"; // string non-empty
Rcpp::List z = Rcpp::List::create(Rcpp::Named("myresult") = nullptr);
if (mystring.empty()) {
z["myresult"] = R_NilValue;
} else {
z["myresult"] = mystring;
}
return z ;
}