2017-07-18 132 views
1

我想使用的功能模板to_string轉換一個intstring,在C++中是沒有問題的,但如果我在R請勿它,它給了我下面的錯誤:如何在R中通過Rcpp使用C++函數模板?

main.cpp: In function 'std::string to_string(T)': 
main.cpp:38:11: error: 't' was not declared in this scope 
ss << t; 
    ^
main.cpp: In function 'SEXPREC* sourceCpp_1_to_string(SEXP)': 
main.cpp:134:36: error: 'T' was not declared in this scope 
Rcpp::traits::input_parameter<T>::type tSEXP(tSEXPSEXP); 
           ^
main.cpp:134:38: error: template argument 1 is invalid 
Rcpp::traits::input_parameter<T>::type tSEXP(tSEXPSEXP); 
           ^
main.cpp:134:46: error: expected initializer before 'tSEXP' 
Rcpp::traits::input_parameter<T>::type tSEXP(tSEXPSEXP); 
             ^
main.cpp:135:44: error: 'tSEXP' was not declared in this scope 
rcpp_result_gen = Rcpp::wrap(to_string(tSEXP)); 
             ^
    make: *** [main.o] Error 1 

我很困惑,是有替代?

//[[Rcpp::export]] 
template <typename T> 
std::string to_string(T t) 
{ 
    std::ostringstream ss; 
    ss << t; 
    return ss.str(); 
} 

回答

2

R從根本上不知道模板。事實上,R和C++之間的接口是一個C ABI,所以所有的C限制都適用。

因此,您不僅可以導出函數模板,還可以無意義地調用非導出模板,因爲您從R獲得的類型是動態的運行時類型,而不是靜態類型。您將需要執行運行時類型分派。

+0

感謝信息 – Moritz

1

對於Konrad的回答,我無話可說,爲什麼你的嘗試失敗了;但從過去的經驗,我會建議(編輯:見更新)推遲到Rcpp::as轉換而不是std::ostringstream,因爲前者依賴於C級Rf_coerceVector(IIRC),因此應產生更爲符合R的as.character (例如,浮點數,DatePOSIXt值)。在這兩種情況下,RCPP_RETURN_VECTOR macro是你的朋友,消除了一堆的樣板:

#include <Rcpp.h> 
using namespace Rcpp; 

template <int RTYPE> 
CharacterVector as_character(const Vector<RTYPE>& x) { 
    return as<CharacterVector>(x); 
} 

// [[Rcpp::export]] 
SEXP to_string(SEXP t) 
{ 
    RCPP_RETURN_VECTOR(as_character, t); 
} 

/*** R 

to_string(1) 
# [1] "1" 

to_string(1.5) 
# [1] "1.5" 

to_string(1.5 + 2i) 
# [1] "1.5+2i" 

to_string(TRUE) 
# [1] "TRUE" 

to_string("abc") 
# [1] "abc" 

to_string(Sys.Date()) 
# [1] "2017-07-18" 

to_string(Sys.time()) 
# [1] "2017-07-18 06:48:58" 

*/ 

更新:正如德克向我指出的異地,沒有必要爲模板功能+ RCPP_RETURN_VECTOR成語在這種特殊情況下,因爲我的模板函數as_character只是調用CharacterVector的構造函數。以下是等效的,但要簡單得多:

#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
CharacterVector to_string(SEXP t) { 
    return CharacterVector(t); 
} 
+0

感謝ü了很多,這是非常有幫助 – Moritz