[Rcpp-devel] "expecting a string" and not finding it in a CharacterVector

Kevin Ushey kevinushey at gmail.com
Fri Feb 8 02:05:20 CET 2013


Perhaps this will narrow down the 'why as seems to fail'. I'm looking at
the Rcpp 0.10.2 source. (hopefully I've got this right):

Rcpp's 'as' uses ::Rf_isString to check whether the item passed is a
string; or more specifically, a STRSXP. However, elements within a
CharacterVector seem to be of 'type' CHARSXP, and hence fail this test, and
throw that exception.

This is kind of surprising since I thought CharacterVectors / StringVectors
were defined as (high-level) containers for STRSXPs ? Certainly, that's
what we see in Rcpp/instantiation.h ...

Sample code:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
StringVector check( StringVector x ) {
  Rcout << "The type of x is: " << ::TYPEOF( x ) << std::endl;
  Rcout << "The type of x(0) is: " << ::TYPEOF( x(0) ) << std::endl;
  Rcout << "The integer associated with STRSXPs is: " << STRSXP <<
std::endl;
  Rcout << "The integer associated with CHARSXPs is: " << CHARSXP <<
std::endl;
  Rcout << "Is x a string?: " << ::Rf_isString(x) << std::endl;
  Rcout << "Is x(0) a string?: " << ::Rf_isString(x(0)) << std::endl;
  return x;
}

/*** R
check( c("a", "b", "c") )
*/

gives me

The type of x is: 16
The type of x(0) is: 9
The integer associated with STRSXPs is: 16
The integer associated with CHARSXPs is: 9
Is x a string?: 1
Is x(0) a string?: 0
[1] "a" "b" "c"

Perhaps someone can illuminate further...
-Kevin

On Thu, Feb 7, 2013 at 10:55 AM, Davor Cubranic <cubranic at stat.ubc.ca>wrote:

> I tracked this down to const-ness:
>
>
> bar <- cxxfunction(signature(xs_="character"), plugin='Rcpp', body='
> const CharacterVector xs(xs_);
> const std::string x(xs(0));
> Rcout << x << std::endl;')
>
>
> fails with the compile error mentioned in my last message, while
>
> foo <- cxxfunction(signature(xs_="character"), plugin='Rcpp', body='
> CharacterVector xs(xs_);
> std::string x(xs(0));
> Rcout << x << std::endl;')
>
> foo(month.abb)
>
>
> works fine. I'll be happy to add a unit test to the package if the devs
> want it.
>
> And to go back to my initial qustion: I'm still not sure why
> "as<std::string>" doesn't work:
>
> baz <- cxxfunction(signature(xs_="character"), plugin='Rcpp', body='
> CharacterVector xs(xs_);
> std::string x = as<std::string>(xs(0));
> Rcout << x << std::endl;')
>
> baz(month.abb)
>
>
> will throw "expecting a string".
>
> Davor
>
>
> On 2013-02-07, at 10:27 AM, Davor Cubranic wrote:
>
> On 2013-02-07, at 10:15 AM, Kevin Ushey wrote:
>
> One trick to get around this is to 'as' the entire CharacterVector into a
> std::vector< std::string >, and then index based off of that.
>
> My guess is though, elements of CharacterVectors are 'const char*' s, so
> to convert them to strings you might want to just use std::string
> constructor, eg. std::string( xs(0) ).
>
>
> That used to work with 0.10.0, but when I upgraded this morning to 0.10.2,
> gives me the following compile error:
>
> rcppdb.cpp:131: error: no matching function for call to
> 'std::basic_string<char, std::char_traits<char>, std::allocator<char>
> >::basic_string(SEXPREC* const&)'
> /usr/include/c++/4.2.1/bits/basic_string.tcc:233: note: candidates are:
> std::basic_string<_CharT, _Traits, _Alloc>::basic_string(typename
> _Alloc::rebind<_CharT>::other::size_type, _CharT, const _Alloc&) [with
> _CharT = char, _Traits = std::char_traits<char>, _Alloc =
> std::allocator<char>]
> /usr/include/c++/4.2.1/bits/basic_string.tcc:226: note:
> std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*,
> const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>,
> _Alloc = std::allocator<char>]
> /usr/include/c++/4.2.1/bits/basic_string.tcc:219: note:
> std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*,
> typename _Alloc::rebind<_CharT>::other::size_type, const _Alloc&) [with
> _CharT = char, _Traits = std::char_traits<char>, _Alloc =
> std::allocator<char>]
> /usr/include/c++/4.2.1/bits/basic_string.tcc:208: note:
> std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const
> std::basic_string<_CharT, _Traits, _Alloc>&, typename
> _Alloc::rebind<_CharT>::other::size_type, typename
> _Alloc::rebind<_CharT>::other::size_type, const _Alloc&) [with _CharT =
> char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
> /usr/include/c++/4.2.1/bits/basic_string.tcc:197: note:
> std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const
> std::basic_string<_CharT, _Traits, _Alloc>&, typename
> _Alloc::rebind<_CharT>::other::size_type, typename
> _Alloc::rebind<_CharT>::other::size_type) [with _CharT = char, _Traits =
> std::char_traits<char>, _Alloc = std::allocator<char>]
> /usr/include/c++/4.2.1/bits/basic_string.tcc:183: note:
> std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const
> std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits =
> std::char_traits<char>, _Alloc = std::allocator<char>]
> /usr/include/c++/4.2.1/bits/basic_string.tcc:191: note:
> std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Alloc&)
> [with _CharT = char, _Traits = std::char_traits<char>, _Alloc =
> std::allocator<char>]
> /usr/include/c++/4.2.1/bits/basic_string.h:2065: note:
> std::basic_string<_CharT, _Traits, _Alloc>::basic_string() [with _CharT =
> char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
> make: *** [rcppdb.o] Error 1
>
> Perhaps this is caused by the same bug, introduced somewhere post-0.10.0.
>
> Davor
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130207/f0cedcb3/attachment.html>


More information about the Rcpp-devel mailing list