如何使用 __cpp_lib_* 功能测试宏?
How do I use the __cpp_lib_* feature test macros?
我想使用 feature test macros 检查 std::filesystem
是否可用,但即使我知道 std::filesystem
存在,__cpp_lib_filesystem
也没有定义。例如下面的测试程序:
#include <iostream>
int main () {
std::cout << "__cpp_lib_filesystem: "
#ifdef __cpp_lib_filesystem
<< __cpp_lib_filesystem
#else
<< "not defined"
#endif
<< std::endl;
std::cout << "__has_include(filesystem): "
#ifndef __has_include
<< "don't have __has_include"
#elif __has_include(<filesystem>)
<< "yes"
#else
<< "no"
#endif
<< std::endl;
}
// also, this compiles:
#include <filesystem>
std::filesystem::path test;
使用 gcc 8.1(我的实际目标编译器)和 gcc 11.2 输出,--std=c++17
:
__cpp_lib_filesystem: not defined
__has_include(filesystem): yes
Here it is on Compiler Explorer.
我也试过包含 <version>
,但是对于 GCC 8.1,它不存在:
<source>:2:10: fatal error: version: No such file or directory
#include <version>
^~~~~~~~~
compilation terminated.
此外,the note here 说:
Library feature-test macros - defined in the header <version> (C++20)
这意味着库功能测试宏不在 <version>
中直到 C++20,这不适用于 C++17(尽管我不是非常清楚这是否意味着 header 是 C++20 功能,或者 macros 是否是 C++20 功能)。
现在,在这种特殊情况下,我知道我可以通过以下方式对其进行测试:
#if defined(__has_include) && __has_include(<filesystem>)
// ...
#else
// ...
#endif
这在这里行得通,因为文件系统是在 C++17 中正式添加的,并且 __has_include
自 C++17 以来就已经存在(或者可能更早,我不知道)——也就是说,不应该不会出现 __has_include
不可用但 std::filesystem
可用的情况。所以没关系。
但是,我的问题是__cpp_lib_filesystem
:为什么上面的测试中没有定义呢?我错过了什么/如何使用它?
有两种使用__cpp_lib_XXX
宏的方法:
其实包含了对应的header:https://godbolt.org/z/xo68acnrz
- 并且给定的库还需要在给定的 C++ 版本中支持此类功能
- 例如,即使包含
<vector>
,__cpp_lib_constexpr_vector
也不会在 C++17 下定义。
使用 C++20,并包含 <version>
header.
我想使用 feature test macros 检查 std::filesystem
是否可用,但即使我知道 std::filesystem
存在,__cpp_lib_filesystem
也没有定义。例如下面的测试程序:
#include <iostream>
int main () {
std::cout << "__cpp_lib_filesystem: "
#ifdef __cpp_lib_filesystem
<< __cpp_lib_filesystem
#else
<< "not defined"
#endif
<< std::endl;
std::cout << "__has_include(filesystem): "
#ifndef __has_include
<< "don't have __has_include"
#elif __has_include(<filesystem>)
<< "yes"
#else
<< "no"
#endif
<< std::endl;
}
// also, this compiles:
#include <filesystem>
std::filesystem::path test;
使用 gcc 8.1(我的实际目标编译器)和 gcc 11.2 输出,--std=c++17
:
__cpp_lib_filesystem: not defined
__has_include(filesystem): yes
Here it is on Compiler Explorer.
我也试过包含 <version>
,但是对于 GCC 8.1,它不存在:
<source>:2:10: fatal error: version: No such file or directory
#include <version>
^~~~~~~~~
compilation terminated.
此外,the note here 说:
Library feature-test macros - defined in the header <version> (C++20)
这意味着库功能测试宏不在 <version>
中直到 C++20,这不适用于 C++17(尽管我不是非常清楚这是否意味着 header 是 C++20 功能,或者 macros 是否是 C++20 功能)。
现在,在这种特殊情况下,我知道我可以通过以下方式对其进行测试:
#if defined(__has_include) && __has_include(<filesystem>)
// ...
#else
// ...
#endif
这在这里行得通,因为文件系统是在 C++17 中正式添加的,并且 __has_include
自 C++17 以来就已经存在(或者可能更早,我不知道)——也就是说,不应该不会出现 __has_include
不可用但 std::filesystem
可用的情况。所以没关系。
但是,我的问题是__cpp_lib_filesystem
:为什么上面的测试中没有定义呢?我错过了什么/如何使用它?
有两种使用__cpp_lib_XXX
宏的方法:
其实包含了对应的header:https://godbolt.org/z/xo68acnrz
- 并且给定的库还需要在给定的 C++ 版本中支持此类功能
- 例如,即使包含
<vector>
,__cpp_lib_constexpr_vector
也不会在 C++17 下定义。
- 例如,即使包含
- 并且给定的库还需要在给定的 C++ 版本中支持此类功能
使用 C++20,并包含
<version>
header.