将 CMake 配置为使用最新的可用 C++ 标准

Configure CMake to use newest available C++ standard

提问人:Shawn McAdam 提问时间:7/27/2023 最后编辑:starballShawn McAdam 更新时间:7/27/2023 访问量:82

问:

我正在使用 CMake 构建一个 C++ 库。是否可以将 C++ 标准设置为用户编译器支持的最新发布标准?我检查了变量CXX_STANDARD的文档,但它只显示了如何使用一个特定的标准。

赋予动机:

我希望我的库与 C++11 兼容,但我也想使用较新的 C++ 标准的功能(如果可用)。例如,我定义了以下宏。

#if (__cplusplus > 201700L || _MSVC_LANG > 201700L)
#define IF_CONSTEXPR_MACRO if constexpr
#else
#define IF_CONSTEXPR_MACRO if
#endif

这对于仅标头库非常有用,因为

  1. 该代码与旧的 C++ 标准兼容,并且
  2. 如果用户使用 C++17 或更高版本进行编译,他们将获得 constexpr if 的所有优点。

不幸的是,我的库不仅仅是标题。我希望生成的 .so 文件使用该版本(如果可用)。if constexpr

C++ CMake IF-constExpr

评论

0赞 paddy 7/27/2023
如果你试图编译一次 .so 并让它支持多种语言标准,你几乎可以忘记它,除非你用一整套魔术宏调味来复制你的函数、数据结构。如果库用户实际上会使用他们所需的语言标准自己编译它,那么这不是一个大问题,但你仍然需要宏魔术来有条件地启用选定的语言功能。
0赞 Shawn McAdam 7/27/2023
例如,你是说如果用户将我的库编译成 std=c++20 的 .so,那么如果它使用 std=c++17 或更早版本,他们将无法将其与自己的代码链接?
0赞 Shawn McAdam 7/27/2023
@paddy 宏魔术对我来说不是问题,因为我的问题包括有条件地启用至少一个有用的语言功能所需的所有宏魔术
0赞 paddy 7/27/2023
如果接口使用 c++20 功能自动编译,并且您尝试将其链接到使用 c++17 功能的项目中,那么您就不走运了。但是,如果你的库只在内部使用 c++20 功能(例如,这些功能不会影响任何接口),那就没问题了。
0赞 Shawn McAdam 7/27/2023
@paddy是的,在我的情况下,较新的C++功能不会影响界面。我真的只是在内部使用 constexpr if 示例,只要可以在编译时决定 if 语句(但不一定必须如此)。

答:

1赞 starball 7/27/2023 #1

对于 MSVC,可以将编译器 ID 生成器表达式包装在 周围。对于其他编译器,可能需要使用 CheckCXXCompilerFlag 执行多项检查。老实说,如果用于编译目标的编译器版本真的无关紧要,那么告诉用户使用他们想要/拥有的任何东西会简单得多。/std:c++latest

我从您描述的场景中获得了一些 XY 问题共鸣。如果使用该宏的代码与 或 同样有效,那么您实际上并不需要那里,并且可能只需要信任您的编译器进行优化(我认为这是您试图使用该宏实现的目标)。ifif constexprif constexpr

评论

0赞 Shawn McAdam 7/27/2023
谢谢,CheckCXXCompilerFlag 看起来很有前途!是的,我的大部分用例可能都经过优化了。另一个可以实现与我IF_CONSTEXPR_MACRO类似的示例是 C++20 关键字 [[likely]] 或 [[unlikely]]。我认为如果它们可用,它们值得使用,但没有人应该仅仅为了使用这些关键字而将 C++20 作为他们库的最低标准。