检查 C++11 库功能

Checking for C++11 library features

本文关键字:功能 C++11 检查      更新时间:2023-10-16

检查标准库是否存在特定 C++11 功能的好方法是什么?

对于编译器功能,我只是检查了(恕我直言)主要编译器(VC++gcc,目前clang,也许是英特尔)的编译器版本,尽管这不是最好和最灵活的方法,但我还不知道有什么更好的方法,除了clang,它具有非常好的__has_feature宏。

但对于库功能来说,情况更糟,它们没有严格耦合到编译器。目前,我想使用相同的方法来检查VC++的编译器版本(假设它使用自己的库,这很容易)。对于 clang,我至少可以将__has_include用于基于标头的大规模查询。除此之外,我想检查__GLIBCXX__的值(如果定义)可能是一个好主意,但话又说回来,除了当前版本支持的功能之外,我找不到有关哪些特定libstdc++版本引入了哪些功能的任何信息。

这些方法应该保留为预处理器检查等,因为我想在仅标头库中使用它,而无需任何诡辩的配置过程,也不使用任何第三方库(是的,boost 是第三方的)。

  1. 那么,在这些(相当狭窄的)条件下,我检查特定 C++11 库功能的可能性是什么?甚至可能在声明的特定功能或类型的规模上?

  2. 如果检查编译器或库版本仍然是最好的方法,我在哪里可以找到有关特定版本的libstdc++(也许还有其他重要的功能,libc++)支持的特定C++11功能的详细信息?

FWIW 目前我插在 <cstdint> 、C++11 <cmath>功能和std::hash中,但这可能会改变,并且对于一般方法可能并不重要。

除了知道哪个编译器在哪个版本中实现什么并具有适当的定义之外,您在这里真的没有什么好做的。

GCC 有一个用于库功能的特殊表。__has_include的主要问题当然是对旧标准的限制。 libstdc++还具有必要的包含,但这并不意味着启用这些文件内容的必要定义。它也不会告诉您有关可用实现的实际数量(有时不完整)的任何信息。

由于您有一个仅标头库,因此这不适用于您,但仍然很重要:C++11 和 C++03 之间的二进制不兼容性可能会回来咬您。

我真的不会自己处理这些,而是使用Boost.Config。最初它只描述语言功能,但现在已扩展到标准库标头。

您可以编写 autoconf 宏进行检查,如果这样做,请将它们提交给 http://www.gnu.org/software/autoconf-archive/
到目前为止,唯一相关的检查是完全覆盖,而不是单个功能:http://www.gnu.org/software/autoconf-archive/ax_cxx_header_stdcxx_0x.html#ax_cxx_header_stdcxx_0x但这不符合没有复杂配置检查的要求。

除此之外,我想检查__GLIBCXX__的值(如果已定义)可能是一个好主意,

查看__GLIBCXX__的值是没有用的,它包含版本的发布日期,这几乎没有告诉你关于版本的信息(例如,4.6.3 是在 4.7.0 之后发布的,所以在 __GLIBCXX__ 年有一个较晚的日期,但C++11 功能较少。当将libstdc++与GCC一起使用时,您希望使用__GLIBC____GLIBC_MINOR__中的通用GCC版本号来检查版本(通常,您只能将给定版本的libstdc++与GCC版本一起使用。

编辑:从GCC 7开始,有一个由libstdc++头文件定义的新宏,_GLIBCXX_RELEASE,它被定义为与GCC的__GNUC__相同的值,但即使将libstdc++头与非GCC编译器一起使用,仍然可以使用。

但话又说回来,除了当前版本支持的功能之外,我找不到有关哪些特定libstdc++版本引入了哪些功能的任何信息。

以前版本的libstdc++ C++11状态表可在线获得,所有GCC文档都位于其中:http://gcc.gnu.org/onlinedocs/

对于 4.7,它处于 http://gcc.gnu.org/onlinedocs/gcc-4.7.1/libstdc++/manual/manual/status.html#status.iso.2011 状态,对于 4.6,它位于 http://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/manual/manual/status.html#status.iso.200x 对于以前的版本,源代码中包含(但无论如何,4.6 之前版本的覆盖范围非常不完整。

每个版本的发行说明中列出了一些添加的功能,例如 http://gcc.gnu.org/gcc-4.7/changes.html(在libstdc++部分)

编辑:对于C++17库支持,我们现在列出了哪个版本首先添加了该功能,因此您只需要查看最新的文档:https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.201z

FWIW 目前我在 <cstdint> 、C++11 中休息<cmath>功能和std::hash

它们应该存在于具有任何 C++0x/C++11 支持的所有 libstdc++ 版本中。