使用Rcpp开发R包设置C++20编译报错,能否正常构建?
在Rcpp开发的R包中使用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构建该R包?
问题原因与解决方法
错误原因
这个编译错误是因为C++20标准正式移除了std::result_of,它的功能被std::invoke_result替代。而你当前使用的Rcpp版本的内部代码仍在依赖std::result_of,导致在C++20编译模式下触发报错。
解决方法
可以使用C++20构建你的R包,只需通过以下方式解决兼容性问题:
- 优先升级Rcpp到最新版本:新版Rcpp已经完成了对C++20的适配,将
std::result_of替换为了兼容的内部实现或std::invoke_result,直接升级后即可正常编译。 - 临时兼容方案(不推荐长期使用):如果暂时无法升级Rcpp,可以在包的
src/Makevars(Windows系统对应src/Makevars.win)文件中添加以下编译规则,让Rcpp相关代码使用较低的C标准编译,同时你的业务代码使用C20:# 为自己的代码指定C++20标准 PKG_CXXFLAGS = -std=c++20 # 获取Rcpp的头文件路径 RCPP_INCLUDE = $(shell Rscript -e 'cat(system.file("include", package = "Rcpp"))') # 对Rcpp头文件使用C++17标准编译(避开C++20的移除规则) CXXFLAGS += -isystem $(RCPP_INCLUDE) -std=c++17
内容的提问来源于stack exchange,提问作者Alessandro Avellone
相关产品推荐
相关产品推荐

