clang 6 不支持 unordered_map::merge?

mrk*_*rks 5 c++ unordered-map clang clang++ c++17

通过这个简单的例子,我得到了一个编译错误:

#include <unordered_map>

int main() {
    std::unordered_map<int, int> a, b;
    a.merge(b);
}
Run Code Online (Sandbox Code Playgroud)

错误:

$ clang++ -std=c++17 merge.cpp
merge.cpp:5:4: error: no member named 'merge' in 'std::__1::unordered_map<int, int, std::__1::hash<int>, std::__1::equal_to<int>, std::__1::allocator<std::__1::pair<const int, int> > >'
        a.merge(b);
        ~ ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

版本:

$ clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-apple-darwin17.5.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
Run Code Online (Sandbox Code Playgroud)

根据 cppreference,从 C++17 开始这应该是合法的。GCC 7 很乐意编译它。

Kon*_*niv 2

我有同样的问题。我很愤怒,为什么我无法使用 macOS 10.14.6编译使用unordered_map::merge() 的应用程序

\n

unordered_map::merge() 是在 c++17 中添加的,提案P0083R3“拼接映射和集合(修订版 5) ”,请参阅github Blame

\n

文档介绍了常见编译器对新 C++ 功能的支持。找到“拼接映射和集”行并检查编译器版本。

\n

“拼接映射和集合”编译器支持:

\n
+-----------------------+---------------------+------+\n| Compiler              | Version             | Link |\n+-----------------------+---------------------+------+\n| GCC libstdc++         |                 7.1 | [1]  |\n| Clang libc++          |                 8.0 | [2]  |\n| MSVC Standard Library | 19.12 (VS 2017 15.5)| [3]  |\n| Apple Clang           |                   - | [4]  |\n+-----------------------+---------------------+------+\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html
  2. \n
  3. https://libcxx.llvm.org/Cxx1zStatus.html#cxx1z-status
  4. \n
  5. https://learn.microsoft.com/cpp/overview/visual-cpp-language-conformance?view=vs-2019
  6. \n
  7. Apple LLVM 有 clang 编译器的特殊实现,请参见下面的描述
  8. \n
\n

如果您请求 clang 版本,您会得到如下内容:

\n
\xe2\x9e\x9c ~ clang++ --version\n\nApple LLVM version 10.0.1 (clang-1001.0.46.4)\nTarget: x86_64-apple-darwin18.7.0\nThread model: posix\nInstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin\n
Run Code Online (Sandbox Code Playgroud)\n

苹果的 clang 版本号与官方版本号无关。一些用户尝试在这里映射苹果和官方的 clang 版本。我认为,这并不总是可能的。

\n

另外,与其他编译器不同,我找不到不同 Apple Clang 版本的 C++ 标准支持状态的详尽表(如果有,请在评论中分享)。我们拥有的只是官方xcode 发行说明

\n

但 mac OS 用户仍然可以利用 c++17 的所有新功能。你应该只......安装原始的llvm。详细指南请参阅Phillip Johnston 的文章“在 OSX 上安装 LLVM/Clang”

\n

使用brew安装llvm更安全:

\n
\n

llvm 仅是 keg,这意味着它没有符号链接到 /usr/local,\n因为 macOS 已经提供了此软件,并行安装另一个\n版本可能会导致各种麻烦。

\n
\n

安装llvm:

\n
// optional "--with-toolchain" from article is deprecated\nbrew install llvm\n
Run Code Online (Sandbox Code Playgroud)\n

检查llvm的状态

\n
\xe2\x9e\x9c ~ brew info llvm\nllvm: stable 8.0.1 (bottled), HEAD [keg-only]\nNext-gen compiler infrastructure\nhttps://llvm.org/\n/usr/local/Cellar/llvm/8.0.1 (6,807 files, 3.3GB)\n  Poured from bottle on 2019-09-14 at 14:19:29\nFrom: https://github.com/Homebrew/homebrew-core/blob/master/Formula/llvm.rb\n==> Dependencies\nBuild: cmake \xe2\x9c\x94\nRequired: libffi \xe2\x9c\x94, swig \xe2\x9c\x94\n==> Requirements\nBuild: xcode \xe2\x9c\x94\n==> Options\n--HEAD\n    Install HEAD version\n==> Caveats\nTo use the bundled libc++ please add the following LDFLAGS:\n  LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"\n\nllvm is keg-only, which means it was not symlinked into /usr/local,\nbecause macOS already provides this software and installing another version in\nparallel can cause all kinds of trouble.\n\nIf you need to have llvm first in your PATH run:\n  echo \'export PATH="/usr/local/opt/llvm/bin:$PATH"\' >> ~/.zshrc\n\nFor compilers to find llvm you may need to set:\n  export LDFLAGS="-L/usr/local/opt/llvm/lib"\n  export CPPFLAGS="-I/usr/local/opt/llvm/include"\n
Run Code Online (Sandbox Code Playgroud)\n

检查 clang 版本:

\n
\xe2\x9e\x9c ~ /usr/local/Cellar/llvm/8.0.1/bin/clang++ --version\nclang version 8.0.1 (tags/RELEASE_801/final)\nTarget: x86_64-apple-darwin18.7.0\nThread model: posix\n
Run Code Online (Sandbox Code Playgroud)\n

配置项目

\n

现在您可以定义编译器,我使用 CMake 并在 CMakeLists.txt 中添加行:

\n
set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/8.0.1/bin/clang")\nset(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/8.0.1/bin/clang++")\nset(CMAKE_CXX_STANDARD 17)\n
Run Code Online (Sandbox Code Playgroud)\n

或传递 cmake 命令的选项:

\n
\xe2\x9e\x9c ~ cmake \\\n  -D CMAKE_C_COMPILER="/usr/local/Cellar/llvm/8.0.1/bin/clang" \\\n  -D CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/8.0.1/bin/clang++" \\\n  /path/to/CMakeLists.txt\n
Run Code Online (Sandbox Code Playgroud)\n

或定义环境变量:

\n
\xe2\x9e\x9c ~ export CC=/usr/local/Cellar/llvm/8.0.1/bin/clang\n\xe2\x9e\x9c ~ export CXX=/usr/local/Cellar/llvm/8.0.1/bin/clang++\n\xe2\x9e\x9c ~ cmake /path/to/CMakeLists.txt\n
Run Code Online (Sandbox Code Playgroud)\n