std :: variant <> :: get()无法与Apple LLVM 10.0一起编译

Mik*_*hke 7 c++ variant llvm-clang c++17

我在玩与C ++ 17的std ::变异类型,并试图编译cppreference示例代码get()

#include <variant>
#include <string>

int main()
{
    std::variant<int, float> v{12}, w;
    int i = std::get<int>(v);
    w = std::get<int>(v);
    w = std::get<0>(v); // same effect as the previous line

//  std::get<double>(v); // error: no double in [int, float]
//  std::get<3>(v);      // error: valid index values are 0 and 1

    try {
      std::get<float>(w); // w contains int, not float: will throw
    }
    catch (std::bad_variant_access&) {}
}
Run Code Online (Sandbox Code Playgroud)

在XCode 10中。我的项目设置为C ++ 17,但是出现编译器错误:

调用不可用的功能'get':macOS 10.14中引入

'bad_variant_access'不可用:在macOS 10.14中引入

这有两种令人惊讶的方式:如果std::variant我支持的是该版本,并且它与受支持的C ++方言无关(并且项目的部署目标为10.14),则它应该编译是否受支持并且关于macOS 10.14的提示很奇怪。 。

这是我做错了还是clang中的错误?

Tob*_*obi 10

从标准头文件中的macOS 10.14(以及相应的iOS,tvOS和watchOS)开始,所有std::variant可能抛出的功能std::bad_variant_access都标记为可用。这是因为std::bad_variant_access::what()没有inline(因此libc++.dylib由OS提供)定义了虚拟方法。

如果您想std::variant在运行于旧版OS上的应用中使用,请使用std::get_if。在您的示例中:

if (auto* p = std::get_if<int>(&w)) {
  // use *p
} else {
  // error handling
}
Run Code Online (Sandbox Code Playgroud)

您也可以使用w.index()和预先检查std:: holds_alternative <int>(w)

编辑:还可以看到我对类似问题的回答std::visit(不幸的是,它没有那么方便的解决方法)

  • 很好的解释 - 现在我们知道**为什么**存在此限制(以及解决方法)! (2认同)

Mik*_*hke 5

事实证明,该项目设置为 macOS 10.14,但实际的构建目标仍然是 10.13。一旦我将其恢复为继承部署目标,测试代码就开始正常编译。

这是一个有趣的变化,因为可以安装 XCode 10(以及 LLVM 10.0)并用于在 10.13 上构建 C++17 应用程序。

  • 是的,如果代码旨在与默认编译器一起工作。由于我主要不是为*Mac 开发,只是在*Mac 上开发,所以我可以自由地使用其他编译器。仍然很遗憾的是,Apple 很刻薄,允许完全正常的非操作系统相关功能只能在最新的 macOS/iOS/… 版本上运行。 (6认同)
  • 这似乎是苹果方面故意破坏,以鼓励Mojave升级。官方的LLVM(可以用Homebrew安装)完全没有问题。 (3认同)