我有一个项目,由于对 std 库中的方法的未知调用,无法由其他人编译。
我怀疑这是由于该家伙的 g++ 版本(9.4.2)所致,因为该函数是在 std 20 标准中添加的。为了测试情况是否如此,我安装了 g++-9(版本 9.5.0)并将
/usr/bin/g++
符号链接指向 g++-9,并偶然发现了另一个问题(问题)。
当我跑步时
$ g++-9 -std=c++20
g++-9: error: unrecognized command line option ‘-std=20’; did you mean ‘-std=c2x’?
g++-9: fatal error: no input files
compilation terminated.
我收到一条错误消息,指出 std 标准版本 20 未知。
但是当我尝试在
CMakeLists.txt
: 中使用以下行生成 cmake 项目的构建文件时
target_compile_features(${PROJECT_NAME}
PUBLIC
cxx_std_20
)
我没有收到任何错误。但是当用 23 替换 20 时:
target_compile_features(${PROJECT_NAME}
PUBLIC
cxx_std_23
)
我收到错误
CMake Error at CMakeLists.txt:74 (target_compile_features):
target_compile_features The compiler feature "cxx_std_23" is not known to
CXX compiler
"GNU"
version 9.5.0.
为什么 C++20 标准对于 g++ 来说是未知的,但在使用 cmake 生成构建文件时却是已知的?
这是某种后续问题:
当我尝试编译我的项目时,出现错误:
error: ‘std::stringstream’ {aka ‘class std::__cxx11::basic_stringstream<char>’} has no member named ‘view’
和 view 是在 c++20 中添加的。难道,那个view是jet的,c++2a中没有添加吗?
好吧...如果您的编译器是 GCC 9.5.0,那么 CMake 说您的编译器不了解 C++23 的原因是...它不了解?
https://en.cppreference.com/w/cpp/compiler_support
cppreference.com 的编译器支持表表示 GCC v9 “了解”C++23 的唯一内容是“缩小 static_assert
和
constexpr if
中的上下文转换”
GCC 9.5.0 出现“g++-9: error: unrecognized command line option '-std=20'; did youmean '-std=c2x'?”的原因可能只是因为 C++ 20 支持尚未完全实施。再次查看 cppreference.com 中的编译器支持表。有许多 C++20 的核心语言功能和库功能,GCC 直到版本 10 才实现(有些甚至在版本 9-13 中,例如“带有填充位的原子比较和交换”)
所以,按照它告诉你的去做,接受你得到的,接受并非所有 C++20 功能都在 GCC 9.5.0 中可用的事实。或者升级你的编译器:P
它与 CMake 的
target_compile_features(... cxx_std_20)
配合使用的原因是... CMake 处理它。参见
模块/编译器/GNU-C.cmake:
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 9.1)
set(CMAKE_C23_STANDARD_COMPILE_OPTION "-std=c2x")
set(CMAKE_C23_EXTENSION_COMPILE_OPTION "-std=gnu2x")
endif()
和模块/编译器/GNU-CXX.cmake:
elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
endif()
-std=c++2a
。根据
man gcc
:
c++2a所以并不是所有的功能都在那里。ISO C++ 标准的下一个修订版,计划于 2020 年进行。支持是高度实验性的,并且几乎肯定会在未来版本中以不兼容的方式发生变化。
GCC 有为尚未发布的标准或支持不完整的标准提供别名的传统。 GCC 9 只知道
c++2a
,并且在 GCC 10 中成为
c++20
的别名。CMake 可以处理这个问题。当不确定 CMake 使用什么作为标准(或任何其他选项)时,请查看
flags.make
或
build.ninja
中的构建目录(取决于您使用的生成器)。