简体   繁体   中英

Unable to compile simple Rcpp function using c++11

Problem background

After upgrading to I don't seem to be able to compile a simple Rcpp function that would use // [[Rcpp::plugins(cpp11)]] . I've tried:

  • Editing Makevars following this answer
  • Running xcode-select --install following linked discussion on compiling C under after upgrade.
  • Changing includes, string / string.h leads to the same error

Code

The function, I've drafted to generate the error:

#include <Rcpp.h>
#include <string.h> // std::string, std::stod
using namespace Rcpp;

// [[Rcpp::plugins(cpp11)]]

// [[Rcpp::export]]
NumericVector convertToDouble(Rcpp::StringVector x) {
    // Numeirc vector to store results
    NumericVector res;
    // Double for converted values
    double converted_double;
    for(Rcpp::StringVector::iterator it = x.begin(); it != x.end(); ++it) {
        // Get [] for vector element
        int index = std::distance(x.begin(), it);
        // Add results to vector
        converted_double = std::stod(x[index]);
        res.push_back(converted_double);
    }
    return res;
}


// Source / test

/*** R
Rcpp::sourceCpp(
    file = "sample_stod.cpp",
    embeddedR = FALSE,
    verbose = TRUE,
    rebuild = TRUE,
    cleanupCacheDir = TRUE,
    showOutput = TRUE)
convertToDouble(c("2.3", "34.25a", "abc32def.43", "12", "1.5"))
*/

Errors

>> Rcpp::sourceCpp(
+     file = "sample_stod.cpp",
+     embeddedR = FALSE,
+     verbose = TRUE,
+     rebuild = TRUE,
+     cleanupCacheDir = TRUE,
+     showOutput = TRUE)

Generated extern "C" functions 
--------------------------------------------------------


#include <Rcpp.h>
// convertToDouble
NumericVector convertToDouble(Rcpp::StringVector x);
RcppExport SEXP sourceCpp_1_convertToDouble(SEXP xSEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< Rcpp::StringVector >::type x(xSEXP);
    rcpp_result_gen = Rcpp::wrap(convertToDouble(x));
    return rcpp_result_gen;
END_RCPP
}

Generated R functions 
-------------------------------------------------------

`.sourceCpp_1_DLLInfo` <- dyn.load('/private/var/folders/7x/kwc1y_l96t55_rwlv35mg8xh0000gn/T/Rtmp2H7VYU/sourceCpp-x86_64-apple-darwin15.6.0-0.12.19/sourcecpp_295d2f3a47a3/sourceCpp_2.so')

convertToDouble <- Rcpp:::sourceCppFunction(function(x) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_convertToDouble')

rm(`.sourceCpp_1_DLLInfo`)

Building shared library
--------------------------------------------------------

DIR: /private/var/folders/7x/kwc1y_l96t55_rwlv35mg8xh0000gn/T/Rtmp2H7VYU/sourceCpp-x86_64-apple-darwin15.6.0-0.12.19/sourcecpp_295d2f3a47a3

/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB -o 'sourceCpp_2.so' --preclean  'sample_stod.cpp'  
clang++ -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I"/Library/Frameworks/R.framework/Versions/3.5/Resources/library/Rcpp/include" -I"/Users/huski/Documents/R Projects/RcppConversion" -I/usr/local/include   -fPIC  -Wall -g -O2 -c sample_stod.cpp -o sample_stod.o
sample_stod.cpp:17:28: error: no matching function for call to 'stod'
        converted_double = std::stod(x[index]);
                           ^~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/string:3910:30: note: candidate function not viable: no known conversion from 'Rcpp::Vector<16, PreserveStorage>::Proxy' (aka 'string_proxy<16, PreserveStorage>') to 'const std::__1::string' (aka 'const basic_string<char, char_traits<char>, allocator<char> >') for 1st argument
_LIBCPP_FUNC_VIS double      stod (const string& __str, size_t* __idx = 0);
                             ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/string:3930:30: note: candidate function not viable: no known conversion from 'Rcpp::Vector<16, PreserveStorage>::Proxy' (aka 'string_proxy<16, PreserveStorage>') to 'const std::__1::wstring' (aka 'const basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >') for 1st argument
_LIBCPP_FUNC_VIS double      stod (const wstring& __str, size_t* __idx = 0);
                             ^
1 error generated.
make: *** [sample_stod.o] Error 1
Error in Rcpp::sourceCpp(file = "sample_stod.cpp", embeddedR = FALSE,  : 
  Error 1 occurred building shared library.
>> 

~/.R/Makevars

# Force use of compilers maintained by Homebrew

# Clang and clang++
CC=/usr/local/opt/llvm/bin/clang 
CXX=/usr/local/opt/llvm/bin/clang++
CXX1X=clang-omp++

Tried passing CC \\ CXX \\ CXX1X variables to use compilers installed via Homebrew but does generate a different error message. All compilation attempts fail on

sample_stod.cpp:17:28: error: no matching function for call to 'stod'


  • Update: can't find stod 在此处输入图片说明

  • g++ --version

      g++ --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 10.0.0 (clang-1000.11.45.2) Target: x86_64-apple-darwin18.0.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin 
  • Current ~/.R/Makevars

      # Force use of compilers maintained by Homebrew # Clang and clang++ # CC=/usr/local/opt/llvm/bin/clang # CXX=/usr/local/opt/llvm/bin/clang++ # CXX1X=clang-omp++ # Fortran # FC=/usr/local/opt/gcc/bin/gfortran # F77=/usr/local/opt/gcc/bin/gfortran # CC=/usr/local/clang4/bin/clang # CXX=/usr/local/clang4/bin/clang++ # LDFLAGS=-L/usr/local/clang4/lib # CPPFLAGS="-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include" CPPFLAGS="-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include" 

So, outside of the initial issue with respect to the compiler shenanigans on macOS (covered here ), you have to help out the compiler when converting to a std::string from a single value in Rcpp::StringVector in this case.

#include <Rcpp.h>

// [[Rcpp::plugins(cpp11)]]

// [[Rcpp::export]]
Rcpp::NumericVector convertToDouble(Rcpp::StringVector x) {
    // Numeirc vector to store results
    std::vector<double> res;

    // Double for converted values
    double converted_double;
    for(Rcpp::StringVector::iterator it = x.begin(); it != x.end(); ++it) {
        // Get [] for vector element
        int index = std::distance(x.begin(), it);

        // Help the conversion to string
        std::string temp = Rcpp::as<std::string>(x[index]);

        // Convert
        converted_double = std::stod(temp);

        // Add to a std vector... Do not use with Rcpp types
        res.push_back(converted_double);
    }

    // Convert and return the Rcpp type as desired.
    return Rcpp::wrap(res);
}

Then, we can run:

convertToDouble(c("2.3", "34.25a", "abc32def.43", "12", "1.5"))
# Error in convertToDouble(c("2.3", "34.25a", "abc32def.43", "12", "1.5")) : stod: no conversion

This errors at: abc32def.43

You may need to do additional cleaning of the string prior to trying a conversion...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM