Reputation: 545488
I’m trying to return a result (in fact, NULL
) invisibly from a C++ function via Rcpp. Unfortunately I am unable to find out how to do this. My first attempt was to set R_Visible
but this global variable is no longer exported; next, I tried calling do_invisible
(the primitive that invisible
calls) directly but, likewise, it’s not exported (and to be honest I’m unsure how to call it correctly anyway).
I then went the roundabout way, calling R’s base::invisible
from Rcpp via an Rcpp::Function
. My code is now something like this:
Rcpp::Function invisible = Rcpp::Environment("package:base")["invisible"];
// [[Rcpp::export]]
SEXP read_value(Rcpp::XPtr<std::vector<int>> x, int index) {
try {
return Rcpp::wrap(x->at(index));
} catch (std::out_of_range const&) {
return invisible(R_NilValue);
}
}
This compiles and executes. Unfortunately, the invisible
call is simply ignored; when calling the function from R with an invalid index, it prints NULL
. I would like it to print nothing.
For testing:
// [[Rcpp::export]]
Rcpp::XPtr<std::vector<int>> make_xvec() {
return Rcpp::XPtr<std::vector<int>>{new std::vector<int>{1, 2, 3}};
}
/*** R
xv = make_xvec()
read_value(xv, 1)
invisible(read_value(xv, 4)) # Works
read_value(xv, 4) # Doesn’t work
*/
Upvotes: 8
Views: 417
Reputation: 368181
Hm. "Ultimately" we always get SEXP .Call(id, SEXP a, SEXP b, ...)
and that ends up (via Rcpp Attributes) with something like
R> rqdb::qdbConnect
function ()
{
.Call(`_rqdb_qdbConnect`)
}
<environment: namespace:rqdb>
R>
which when we call it gives us
R> qdbConnect()
[1] TRUE
R> invisible(qdbConnect())
R>
Can't you just wrap another layer at the R side and call it a day?
I think the key really is that a void
function is possible, but the default is something as the SEXP
. And C++ only has return
so you need R for the invisible
part.
Upvotes: 2