在 libc++ 和 libstdc++ 之间的 std::map 上使用 std::find 时的实现差异
Implementation difference when using std::find on a std::map between libc++ and libstdc++
我试图向一些同事总结 std::find
是如何工作的,我想向他们展示在 std::map
上使用它有多么棘手(以及为什么他们不应该这样做),所以我开始摆弄编译器资源管理器。
我认为我 运行 陷入 libc++
和 libstdc++
之间的实现差异,因为以下代码片段是在前者
上编译的
#include <string>
#include <map>
int main (){
std::map<std::string, int> myMap;
myMap["string1"] = 100;
std::map<std::string, int>::value_type element("string1", 100);
auto it = std::find(myMap.begin(), myMap.end(), element);
}
但编译失败,后者生成以下错误
error: no matching function for call to 'find'
auto it = std::find(myMap.begin(), myMap.end(), element);
^~~~~~~~~
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/streambuf_iterator.h:373:5: note: candidate template ignored: could not match 'istreambuf_iterator' against '_Rb_tree_iterator'
find(istreambuf_iterator<_CharT> __first,
^
1 error generated.
所以我很困惑,我想知道这两者中哪一个是所需的行为。编译器资源管理器链接:
- 使用 libc++ https://godbolt.org/z/KDsMsC
- 使用 libstdc++ https://godbolt.org/z/g3DqlJ
您必须 #include <algorithm>
,如文档所述 here。
您只是幸运地(不幸地)有一个库为您隐含地包含了 header,但您真的不应该依赖它。
如果您查看 C++ 标准,您会发现在使用 header <map>
时,C++ 标准要求包含的唯一 header 是 header<initializer_list>
。对于header<string>
同样有效。那就是唯一需要包含的 header 是 <initializer_list>
.
允许实现在 <map>
和 <string>
中包含任何其他 header。但是它是实现定义的。
当使用 header <iostream>
时,例如 header <string>
会发生类似的情况。一些实现包括 header <string>
中的 header <iostream>
其他的则不这样做。
因此,如果标准未明确指定这些 header 包含在其他使用的 header 中,那么您始终应该包含所有必需的 header。
我试图向一些同事总结 std::find
是如何工作的,我想向他们展示在 std::map
上使用它有多么棘手(以及为什么他们不应该这样做),所以我开始摆弄编译器资源管理器。
我认为我 运行 陷入 libc++
和 libstdc++
之间的实现差异,因为以下代码片段是在前者
#include <string>
#include <map>
int main (){
std::map<std::string, int> myMap;
myMap["string1"] = 100;
std::map<std::string, int>::value_type element("string1", 100);
auto it = std::find(myMap.begin(), myMap.end(), element);
}
但编译失败,后者生成以下错误
error: no matching function for call to 'find'
auto it = std::find(myMap.begin(), myMap.end(), element);
^~~~~~~~~
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/bits/streambuf_iterator.h:373:5: note: candidate template ignored: could not match 'istreambuf_iterator' against '_Rb_tree_iterator'
find(istreambuf_iterator<_CharT> __first,
^
1 error generated.
所以我很困惑,我想知道这两者中哪一个是所需的行为。编译器资源管理器链接:
- 使用 libc++ https://godbolt.org/z/KDsMsC
- 使用 libstdc++ https://godbolt.org/z/g3DqlJ
您必须 #include <algorithm>
,如文档所述 here。
您只是幸运地(不幸地)有一个库为您隐含地包含了 header,但您真的不应该依赖它。
如果您查看 C++ 标准,您会发现在使用 header <map>
时,C++ 标准要求包含的唯一 header 是 header<initializer_list>
。对于header<string>
同样有效。那就是唯一需要包含的 header 是 <initializer_list>
.
允许实现在 <map>
和 <string>
中包含任何其他 header。但是它是实现定义的。
当使用 header <iostream>
时,例如 header <string>
会发生类似的情况。一些实现包括 header <string>
中的 header <iostream>
其他的则不这样做。
因此,如果标准未明确指定这些 header 包含在其他使用的 header 中,那么您始终应该包含所有必需的 header。