C++ 在libc和x2B之间的std::map上使用std::find时的实现差异+;和libstdc++;

C++ 在libc和x2B之间的std::map上使用std::find时的实现差异+;和libstdc++;,c++,c++11,libstdc++,libc++,C++,C++11,Libstdc++,Libc++,我试图向一些同事总结一下std::find是如何工作的,我想向他们展示在std::map上使用它有多么棘手(以及为什么他们不应该这么做),所以我开始在编译器资源管理器上摆弄它 我想我遇到了libc++和libstdc++之间的实现差异,因为下面的代码段是在前者的基础上编译的 #包括 #包括 int main(){ std::map myMap; myMap[“string1”]=100; std::map::value_类型元素(“string1”,100); auto it=std::find

我试图向一些同事总结一下
std::find
是如何工作的,我想向他们展示在
std::map
上使用它有多么棘手(以及为什么他们不应该这么做),所以我开始在编译器资源管理器上摆弄它

我想我遇到了
libc++
libstdc++
之间的实现差异,因为下面的代码段是在前者的基础上编译的

#包括
#包括
int main(){
std::map myMap;
myMap[“string1”]=100;
std::map::value_类型元素(“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.
错误:调用“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_迭代器。h:373:5:忽略候选模板:无法与“\u Rb_树迭代器”匹配
首先查找(istreambuf_迭代器),
^
生成1个错误。
因此,我感到困惑,我想知道这两种行为中哪一种是理想的行为。编译器浏览器链接:

  • 使用libc++
  • 使用libstdc++
    • 您必须
      #包括


      你刚刚得到(联合国)幸运的是,一个库隐含地为您提供了该报头,但您不应该依赖它。

      < P>如果您查看C++标准,当您看到头文件<代码> <代码>时使用的C++头的唯一标头是头<代码> <代码>。t是唯一需要包含的标题是

      允许实现在
      中包含任何其他标题。但它是实现定义的

      例如,当使用头
      时,头
      也会出现类似的情况。一些实现在头
      中包含头
      ,而其他实现则不这样做


      因此,如果标准没有明确指定这些头包含在其他使用的头中,那么您应该始终包含所有必需的头。

      您必须包含头,那么问题出在哪里?@vladfrommosco我想唯一的问题是编译器错误似乎表明参数不匹配“无法将'istreambuf_iterator'与'\u Rb_tree_iterator''匹配@SPD编译器明确表示找不到名称std::find。@我知道。我只是说模板错误通常很容易混淆,这是一个很好的例子。在这种情况下,编译器最好只是抑制它。”不能匹配“istReaBufyTyter”……“行——这将是更直观的,而且我们很可能根本不会花时间在这个帖子上。”SPD最初编译器没有找到这个函数。在找到函数后,编译器可以判断它的参数是否有效。“一个C++头可以包括其他C++头。"这实际上是impl def吗?@L.F.是的,它是实现定义的。它取决于一个实现将包含哪些标题。您是如何得出这个结论的?may!=实现定义的。它也可以是未指定的行为。特别是,它没有列出。@L.F.may表示实现定义的,因为它没有指定确切的h一个实现将包括的eaders。??我试图证明这是未指定的行为,而不是实现定义的行为。(并不是说这种区别与非学究的人有关;-)为什么像
      std::string
      std::map
      这样的标准std类应该依赖于算法来
      #包含其头文件?有什么想法吗?也许字符串实现决定在其方法之一中使用std::find。这是一个实现细节,不用担心,也不用依赖它。