[Rcpp-devel] Working with strings

Romain Francois romain at r-enthusiasts.com
Sun Nov 18 17:07:39 CET 2012


Le 18/11/12 15:35, Hadley Wickham a écrit :
> On Sat, Nov 17, 2012 at 9:23 AM, Romain Francois
> <romain at r-enthusiasts.com> wrote:
>> Le 17/11/12 15:22, Hadley Wickham a écrit :
>>>
>>> Hi all,
>>>
>>> Am I doing something wrong with the functions below, or has this
>>> behaviour not yet been implemented in Rcpp?
>>>
>>>       cppFunction('std::string first_char(const CharacterVector x) {
>>>         return x[0];
>>>       }')
>>
>>
>> Ah.
>>
>>
>>>      cppFunction('std::string first_char(CharacterVector x) {
>> +       return x[0] ;
>> +     }')
>> filee454ce15417.cpp: In function ‘std::string
>> first_char(Rcpp::CharacterVector)’:
>> filee454ce15417.cpp:7: error: conversion from
>> ‘Rcpp::internal::string_proxy<16>’ to non-scalar type ‘std::string’
>> requested
>>
>>
>> Because of the way character vectors are implemented, we had to use a proxy
>> mechanism. so the result of the operator[] is a:
>>
>> string_proxy<16>
>>
>>          which has these two conversion operators:
>>
>>                  operator SEXP() const
>>                          this just retrieves the underlying CHARSXP using
>> STRING_ELT
>>
>>                  operator /*const */ char*() const
>>                          this also applies CHAR() to it to get a C string.
>>
>>
>>
>> I think we tried having an automatic conversion to std::string, but this
>> failed and the compiler was confused.
>>
>>
>> Anyway. Short of automatic conversion, you can use a forced one:
>>
>>      cppFunction('std::string first_char(const CharacterVector x) {
>>        return std::string( x[0] );
>>      }')
>>
>> it works because of "only distance 1" conversion to go from string_proxy and
>> something (in that case char*) the ctor of string will accept.
>
> Do you think it's likely that you'll ever manage to get automatic
> conversion to work?  That'll help me figure out the best way to write
> about it.

Really not sure. We could easily add explicit conversions, e.g. as 
member functions:

cppFunction('std::string first_char(const CharacterVector x) {
         return x[0].as_string() ;
       }')

or some other syntax, but automatic brings lots of compiler issues.

>>>       cppFunction('CharacterVector miss_c() {
>>>         return CharacterVector::create(NA_STRING);
>>>       }')
>>
>>
>> I've seen this too and was about to find my ways to a fix.
>
> Ok, great - thanks!
>
>> This works though:
>>
>> cppFunction('CharacterVector miss_c() {
>>        CharacterVector out(1) ;
>>        out[0] = NA_STRING ;
>>        return out ;
>>      }')
>>
>> Not as convenient. :-/
>
> Yup, that's what I've been using.
>
> Hadley
>


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30

R Graph Gallery: http://gallery.r-enthusiasts.com
`- http://bit.ly/SweN1Z : SuperStorm Sandy

blog:            http://romainfrancois.blog.free.fr
|- http://bit.ly/RE6sYH : OOP with Rcpp modules
`- http://bit.ly/Thw7IK : Rcpp modules more flexible



More information about the Rcpp-devel mailing list