clang 6 不支持 unordered_map::merge?
clang 6 not supporting unordered_map::merge?
对于这个简单的例子,我得到一个编译错误:
#include <unordered_map>
int main() {
std::unordered_map<int, int> a, b;
a.merge(b);
}
错误:
$ 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.
版本:
$ 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
According to cppreference,从C++17开始这应该是合法的。 GCC 7 很乐意编译它。
我有同样的问题。我很生气,为什么我不能使用 macOS 10.14.6
编译使用 unordered_map::merge() 的应用程序
unordered_map::merge() 已在 c++17 中添加,提案为 P0083R3 "Splicing Maps and Sets (Revision 5)", see github blame.
文档呈现 common compilers' support for new C++ features。找到“拼接映射和集合”行并检查编译器版本。
“拼接映射和集合”编译器的支持:
+-----------------------+---------------------+------+
| Compiler | Version | Link |
+-----------------------+---------------------+------+
| GCC libstdc++ | 7.1 | [1] |
| Clang libc++ | 8.0 | [2] |
| MSVC Standard Library | 19.12 (VS 2017 15.5)| [3] |
| Apple Clang | - | [4] |
+-----------------------+---------------------+------+
- https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html
- https://libcxx.llvm.org/Cxx1zStatus.html#cxx1z-status
- https://docs.microsoft.com/cpp/overview/visual-cpp-language-conformance?view=vs-2019
- Apple LLVM 有 clang 编译器的特殊实现,见下面的描述
如果你请求一个 clang 版本,你会得到这样的东西:
➜ ~ clang++ --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
苹果clang版本号与官方版本号无关。一些用户尝试映射 apple 的和官方的 clang 版本 here。我想,这并不总是可能的。
此外,我找不到详尽的 table 不同 Apple Clang 版本的 c++ 标准支持状态,这与其他编译器不同(如果有,请在评论中分享)。我们只有官方 xcode release notes.
但是macOS用户仍然可以利用c++17的所有新特性。你应该只...安装原始的 llvm。详细指南请参阅文章 "Installing LLVM/Clang on OSX" by Phillip Johnston。
使用 brew 安装 llvm 更安全:
llvm is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another
version in parallel can cause all kinds of trouble.
安装llvm:
// optional "--with-toolchain" from article is deprecated
brew install llvm
检查 llvm 的状态
➜ ~ brew info llvm
llvm: stable 8.0.1 (bottled), HEAD [keg-only]
Next-gen compiler infrastructure
https://llvm.org/
/usr/local/Cellar/llvm/8.0.1 (6,807 files, 3.3GB)
Poured from bottle on 2019-09-14 at 14:19:29
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/llvm.rb
==> Dependencies
Build: cmake ✔
Required: libffi ✔, swig ✔
==> Requirements
Build: xcode ✔
==> Options
--HEAD
Install HEAD version
==> Caveats
To use the bundled libc++ please add the following LDFLAGS:
LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
llvm is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have llvm first in your PATH run:
echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.zshrc
For compilers to find llvm you may need to set:
export LDFLAGS="-L/usr/local/opt/llvm/lib"
export CPPFLAGS="-I/usr/local/opt/llvm/include"
检查clang版本:
➜ ~ /usr/local/Cellar/llvm/8.0.1/bin/clang++ --version
clang version 8.0.1 (tags/RELEASE_801/final)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
配置项目
现在你可以定义编译器了,我使用 CMake 并在 CMakeLists.txt 中添加行:
set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/8.0.1/bin/clang")
set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/8.0.1/bin/clang++")
set(CMAKE_CXX_STANDARD 17)
或通过 cmake 命令的选项:
➜ ~ cmake \
-D CMAKE_C_COMPILER="/usr/local/Cellar/llvm/8.0.1/bin/clang" \
-D CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/8.0.1/bin/clang++" \
/path/to/CMakeLists.txt
或定义环境变量:
➜ ~ export CC=/usr/local/Cellar/llvm/8.0.1/bin/clang
➜ ~ export CXX=/usr/local/Cellar/llvm/8.0.1/bin/clang++
➜ ~ cmake /path/to/CMakeLists.txt
对于这个简单的例子,我得到一个编译错误:
#include <unordered_map>
int main() {
std::unordered_map<int, int> a, b;
a.merge(b);
}
错误:
$ 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.
版本:
$ 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
According to cppreference,从C++17开始这应该是合法的。 GCC 7 很乐意编译它。
我有同样的问题。我很生气,为什么我不能使用 macOS 10.14.6
编译使用 unordered_map::merge() 的应用程序unordered_map::merge() 已在 c++17 中添加,提案为 P0083R3 "Splicing Maps and Sets (Revision 5)", see github blame.
文档呈现 common compilers' support for new C++ features。找到“拼接映射和集合”行并检查编译器版本。
“拼接映射和集合”编译器的支持:
+-----------------------+---------------------+------+
| Compiler | Version | Link |
+-----------------------+---------------------+------+
| GCC libstdc++ | 7.1 | [1] |
| Clang libc++ | 8.0 | [2] |
| MSVC Standard Library | 19.12 (VS 2017 15.5)| [3] |
| Apple Clang | - | [4] |
+-----------------------+---------------------+------+
- https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html
- https://libcxx.llvm.org/Cxx1zStatus.html#cxx1z-status
- https://docs.microsoft.com/cpp/overview/visual-cpp-language-conformance?view=vs-2019
- Apple LLVM 有 clang 编译器的特殊实现,见下面的描述
如果你请求一个 clang 版本,你会得到这样的东西:
➜ ~ clang++ --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
苹果clang版本号与官方版本号无关。一些用户尝试映射 apple 的和官方的 clang 版本 here。我想,这并不总是可能的。
此外,我找不到详尽的 table 不同 Apple Clang 版本的 c++ 标准支持状态,这与其他编译器不同(如果有,请在评论中分享)。我们只有官方 xcode release notes.
但是macOS用户仍然可以利用c++17的所有新特性。你应该只...安装原始的 llvm。详细指南请参阅文章 "Installing LLVM/Clang on OSX" by Phillip Johnston。
使用 brew 安装 llvm 更安全:
llvm is keg-only, which means it was not symlinked into /usr/local, because macOS already provides this software and installing another version in parallel can cause all kinds of trouble.
安装llvm:
// optional "--with-toolchain" from article is deprecated
brew install llvm
检查 llvm 的状态
➜ ~ brew info llvm
llvm: stable 8.0.1 (bottled), HEAD [keg-only]
Next-gen compiler infrastructure
https://llvm.org/
/usr/local/Cellar/llvm/8.0.1 (6,807 files, 3.3GB)
Poured from bottle on 2019-09-14 at 14:19:29
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/llvm.rb
==> Dependencies
Build: cmake ✔
Required: libffi ✔, swig ✔
==> Requirements
Build: xcode ✔
==> Options
--HEAD
Install HEAD version
==> Caveats
To use the bundled libc++ please add the following LDFLAGS:
LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
llvm is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have llvm first in your PATH run:
echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.zshrc
For compilers to find llvm you may need to set:
export LDFLAGS="-L/usr/local/opt/llvm/lib"
export CPPFLAGS="-I/usr/local/opt/llvm/include"
检查clang版本:
➜ ~ /usr/local/Cellar/llvm/8.0.1/bin/clang++ --version
clang version 8.0.1 (tags/RELEASE_801/final)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
配置项目
现在你可以定义编译器了,我使用 CMake 并在 CMakeLists.txt 中添加行:
set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/8.0.1/bin/clang")
set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/8.0.1/bin/clang++")
set(CMAKE_CXX_STANDARD 17)
或通过 cmake 命令的选项:
➜ ~ cmake \
-D CMAKE_C_COMPILER="/usr/local/Cellar/llvm/8.0.1/bin/clang" \
-D CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/8.0.1/bin/clang++" \
/path/to/CMakeLists.txt
或定义环境变量:
➜ ~ export CC=/usr/local/Cellar/llvm/8.0.1/bin/clang
➜ ~ export CXX=/usr/local/Cellar/llvm/8.0.1/bin/clang++
➜ ~ cmake /path/to/CMakeLists.txt