英文:
R Package using Rcpp and C++20
问题
我用Rcpp制作了一个简单的R包,但当我在DESCRIPTION中设置SystemRequirements: C++20时,在构建时出现以下错误。
clang++ -arch x86_64 -std=gnu++20 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG  -I'/Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include' -I/opt/R/x86_64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -UNDEBUG -Wall -pedantic -g -O0 -c RcppExports.cpp -o RcppExports.o
   In file included from RcppExports.cpp:4:
   In file included from /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp.h:78:
   In file included from /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp/sugar/sugar.h:31:
   In file included from /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp/sugar/functions/functions.h:42:
   /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp/sugar/functions/sapply.h:36:19: error: no template named 'result_of' in namespace 'std'; did you mean 'traits::result_of'?
           typedef typename ::std::result_of<Function(typename SugarExpression::stored_type)>::type type;
                            ^~~~~~~~~~~~~~~~
                            traits::result_of
   /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp/traits/result_of.h:30:8: note: 'traits::result_of' declared here
   struct result_of{
          ^
   1 error generated.
   make: *** [RcppExports.o] Error 1
   ERROR: compilation failed for package
是否可能使用C++20构建该包?
英文:
I made a simple R Package using Rcpp but when I set
SystemRequirements: C++20
on DESCRIPTION I have the following error on build.
clang++ -arch x86_64 -std=gnu++20 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG  -I'/Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include' -I/opt/R/x86_64/include    -fPIC  -falign-functions=64 -Wall -g -O2  -UNDEBUG -Wall -pedantic -g -O0 -c RcppExports.cpp -o RcppExports.o
   In file included from RcppExports.cpp:4:
   In file included from /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp.h:78:
   In file included from /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp/sugar/sugar.h:31:
   In file included from /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp/sugar/functions/functions.h:42:
   /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp/sugar/functions/sapply.h:36:19: error: no template named 'result_of' in namespace 'std'; did you mean 'traits::result_of'?
           typedef typename ::std::result_of<Function(typename SugarExpression::stored_type)>::type type;
                            ^~~~~~~~~~~~~~~~
                            traits::result_of
   /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/library/Rcpp/include/Rcpp/traits/result_of.h:30:8: note: 'traits::result_of' declared here
   struct result_of{
          ^
   1 error generated.
   make: *** [RcppExports.o] Error 1
   ERROR: compilation failed for package
Is it possible to build the package with C++20?
答案1
得分: 2
最新的Rcpp发布版本(版本1.0.10)发生在一月份。但是支持使用clang++的C++20所需的代码是在二月份添加的,参考https://github.com/RcppCore/Rcpp/pull/1248。您可以从项目的drat仓库获取中间版本:
install.packages("Rcpp", repos="https://RcppCore.github.io/drat")
未经测试,因为您没有提供最小示例。
英文:
The last Rcpp release (version 1.0.10) happend in January. But the code necessary to support C++20 with clang++ was added in February, c.f. https://github.com/RcppCore/Rcpp/pull/1248. You can get intermediate releases from the projects drat repository:
install.packages("Rcpp", repos="https://RcppCore.github.io/drat")
Untested, since you have not provided a minimal example.
答案2
得分: 2
这取决于你的编译器是什么。对我来说(在Ubuntu 22.10中),以下内容有效,并演示了新的三路比较鲸鱼运算符(更多信息在这里)(我将一行长代码进行了缩进以便在这里显示):
Rcpp::cppFunction("int threeway(int a, int b) { auto res = (a <=> b); 
     if (res < 0) return -1; else if (res > 0) return 1; else return 0; }", 
     plugin="cpp20")
threeway(-2, 2)
[1] -1
threeway(2, -2)
[1] 1
threeway(2, 2)
[1] 0
现在,这使用了插件,对于一个包,你可以在DESCRIPTION中使用SystemRequirements:或者在src/Makevars中使用CXX_STD,不需要插件,就像我们多年来一直做的那样。但是,这一部分只涉及R将所需的标志传递给编译器。编译器接下来对代码做什么取决于你使用的是哪个版本的编译器。
现在,正如@Ralf正确指出的,CRAN上的Rcpp版本在从C++17到C++20的更改方面存在问题,因此你需要从GitHub或drat仓库获取发布候选版本。更新版本将在下个月到达CRAN。
英文:
It all depends a little ... on what your compiler is. For me (in Ubuntu 22.10) the following works and demonstrates the new three-way comparison walrus operator (more here) (and I indent what is one long code line for display here)
> Rcpp::cppFunction("int threeway(int a, int b) { auto res = (a <=> b); 
     if (res < 0) return -1; else if (res > 0) return 1; else return 0; }", 
     plugin="cpp20")
> threeway(-2, 2)
[1] -1
> threeway(2, -2)
[1] 1
> threeway(2, 2)
[1] 0
> 
Now, this uses the plugin which is not needed on a package where you either use SystemRequirements: in DESCRIPTION or use CXX_STD in src/Makevars as we have for years.  But that part is only about R dispatching the required flag to the compiler.  What the compiler then can do with the code depends on ... what version of which compiler you have.
Now, as @Ralf correctly pointed out, the Rcpp version at CRAN has an issue with clang++ and a change from C++17 to C++20 so you need the release candidate from GitHub or the drat repo.  An updated version will get to CRAN next month.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论