2

我想做一些跨平台的、可选的使用std::filesystem和使用的代码,如下所示:

#ifdef __has_include
#if __has_include(<version>)
#include <version>
#endif
#endif

#ifdef __cpp_lib_filesystem
#include <filesystem>
// Use of std::filesystem::path
#endif

然后我可以通过-std=c++11-std=c++17有或没有对文件系统的支持。

这几乎在任何地方都可以正常工作,但在没有明确目标平台级别集的最近的 OSX 上。这似乎默认为某些较旧的 OSX 并引发编译错误:

错误:“路径”不可用:在 macOS 10.15 中引入
...
Applications/Xcode_11.3.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/filesystem:739: 24:
注意:“路径”已在此处明确标记为不可用

那么如果这样的代码编译,我应该如何在 OSX 上处理这个而不依赖于配置检查呢?功能检测宏不是__cpp_lib_filesystem意味着不需要这样的配置步骤吗?

4

1 回答 1

0

问题是您设置支持哪个版本的 OSX。

在 OSX/MacOS C++ 标准库是系统的一部分。因此,如果您设置您的程序支持某些版本的 MacOS,编译器将检查该版本的系统是否具有支持特定功能的标准 C++ 库。

因此,例如,您启用 C++17 并不重要,但如果您的程序应该支持 OSX 10.13,则该程序将无法编译:

int foo(std::optional<int> x)
{
   return x.value();
}

因为这可能会引发异常:std::bad_optional_access这是 OS 附带的标准库动态库的一部分。

另一方面,这段代码编译得很好:

int foo(std::optional<int> x)
{
   return x.value_or(0);
}

因为这个版本不会抛出,并且模板代码只会在您的可执行文件中生成。

文件系统功能也存在完全相同的问题。这就是编译器抱怨您需要设置项目以支持 MacOS 10.15 或更高版本的原因。

如果您使用cmake将其添加到 root CMakeLists.txt

# note this entry must be set before any target or project is created
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")

如果您使用的是 Xcode 项目: 在此处输入图像描述

有一种方法可以检测平台并使此 10.15 功能可用。这是描述如何做的答案。这样,您就可以拥有某些功能仅在所需操作系统版本上运行时可用的应用程序。

于 2020-10-07T08:46:27.060 回答