为什么某些C++功能测试宏需要包含头文件?
一些 C++功能测试宏(例如__cpp_lib_three_way_comparison)需要包含头文件(例如<compare>)来测试它们。
这似乎很倒退,例如,也许我只想在我知道编译器支持它时才包含头文件(更准确地说,它使用的是编译器+std lib impl),例如,假设我有my_fancy_string_view并且我想将它定义为std::string_view如果std::string_view可用,但是检测是否std::string_view可用我需要包括<string_view>...
这只是此功能设计中的“错误/oopsie”,还是编译器未预定义所有功能测试宏的充分理由?我的猜测是可能允许混合 STL 实现,例如某些平台上的 clang 使用 gcc 的 std lib 实现,但我再次假设编译器知道他们使用什么 std lib 实现,因此他们可以调整预定义的宏。
我知道<version>标头存在,但这对我没有帮助,因为它仅在 C++20 中添加。当我的基线是 C++20 时,它可能在 10 多年后很好,但现在它不是那么有用。
此外,添加此标题的事实可能表明实际上需要“重”包含是一个错误,但我想就此获得专家意见。
PS这是添加的提案<version>,但它非常小,所以没有细节......
回答
但是要检测 std::string_view 是否可用,我需要包含 <string_view> ...
不,你必须先使用__has_include(<string_view>)。
库功能由标题定义,因为库是由标题定义的。在大多数情况下,编译器在编译之前无法知道头文件的内容。
是的,标准库的许多部分可以跨编译器使用。虽然某些组件特定于编译器/平台,但可以在不依赖平台/编译器细节的情况下实现很多标准库。标准库,或者至少其中的大部分,可以独立于它挂钩的编译器进行更新。