关于c ++:cplusplus.com有什么问题?


What's wrong with cplusplus.com?

这也许不是一个完全适合这个问题的论坛,但让我试一试,冒着被移走的危险。

对于C++标准库有几个引用,包括宝贵的ISO标准、MSDN、IBM、CPP首选和CPLUS PLUS。就个人而言,在编写C++时,我需要一个具有快速随机访问、短加载时间和使用示例的引用,并且我发现CPLUSPPLUS非常有用。但是,我经常在这里听到关于那个网站的负面意见,所以我想具体说明一下:

cplusplus.com给出的错误、误解或错误建议是什么?使用它进行编码决策有什么风险?

让我再补充一点:我想在这里用标准的准确引用回答问题,因此我想立即发布可用的链接,如果不是这个问题,cplusplus.com将是我的首选网站。


编辑:此答案编写后,已修复std::remove的文档。同样的事情也适用于list::remove

让我给你举个例子来说明cpluscplus.com是如何出错的。

考虑来自std::remove函数。

事实上,std::remove不会从容器中移除该项。这是因为std::remove只与一对迭代器一起工作,对实际包含这些项的容器一无所知。实际上,std::remove不可能知道底层容器,因为它无法从一对迭代器中找到迭代器所属的容器。所以std::remove并没有真正删除这些项目,仅仅是因为它不能。从容器中实际删除项的唯一方法是调用该容器上的成员函数。

因此,如果要删除这些项,请使用"删除删除"习惯用法:

1
 v.erase(std::remove(v.begin(), v.end(), 10), v.end());

但是cplusplus.com给出了关于std::remove的错误信息。它说

Notice that this function does not alter the elements past the new end, which keep their old values and are still accessible.

这是不对的。范围[new_end, old_end)中的迭代器仍然是不可引用的,但这并不意味着它们保留旧值并且仍然可以访问。未指明。

同样,cplusplus.com也给出了关于list::remove的错误信息。它说,

Notice that a global algorithm function, remove, exists with a similar behavior but operating between two iterators.

这是完全错误的。全局删除,即std::removelist::remove不同,因为我们看到前者不能真正从容器中删除项目,而后者(成员函数)确实可以删除项目,因为它可以。

此答案是从我在以下主题中的另一个答案中复制的,几乎没有修改:

  • stl remove不按预期工作?

注:由于我最近在回答上述主题时遇到了这个问题,所以我记得。在过去的两年里,我遇到了很多错误,但我不记得了。如果我再遇到的话,我可能会再增加一些。


我要提出一个稍微相反的意见。在cplusplus.com上有很多好的信息。选择它到死,是的,当然它有它的问题,但什么网站没有?当然不是这个网站。住在玻璃房子里的人不应该扔石头。这里也有很多错误信息。有公认的答案是完全错误的,被否决的答案(有些是否定的!)那是正确的。

cplusplus.com的一个问题是它是一个封闭的站点;对于提到的大多数其他参考站点也是如此。这与社区开发站点(如堆栈溢出)的粒度不符。获得可信编辑的能力并不需要那么长时间,即使是最新的新手也可以很容易地提出改进建议。将其与cplusplus.com进行比较。如果你不在他们的工作人员中,你是一个永远的新手。即使您是wg21的关键成员,如果您在该站点的某个地方看到一个bug,您也必须通过他们的电子邮件报告机制。诅咒!

一个解决方案将是我们在这个网站上开发我们自己的C++参考。这需要相当多的工作。我们必须小心,不要太学究/太技术化;很明显,cplusplus.com至少雇佣了一些技术编辑,让这些学究望而却步。我们必须保持信息井然有序;这里的常见问题解答没有井然有序。我们还必须非常小心,不要直接从标准中说太多,这是违法的。


http://www.cplusplus.com/reference/clibrary/cstring/strncpy/

没有提到"如果复制发生在重叠的对象之间,则行为是未定义的"(C89标准中的4.11.2.4)。我没有一个拷贝到C90的手,这是C++ 03实际上提到的,但是它们应该只在页面编号之类的东西上有所不同。


cplusplus.com提供的文档通常不正确或不完整。

一旦出现这样的例子,cplusplus.com上的atoi文档。

字符串转换为整数在返回部分中,如果在使用函数时无法执行转换,则不会提及0返回值。

cplusplus.com返回部分声明"…如果转换的值将超出int可表示值的范围,则会导致未定义的行为。"

这是正确的,根据标准"如果字符串的数值不能用in t表示,那么行为是未定义的"。

但是,该部分不完整,因为它没有提到0作为返回值,这可能会产生误导。短语"…不执行转换,返回零。"在描述段落之前已满足,但在返回部分必须满足。

cplusplus.com上给出的许多示例源代码都不正确。许多新来的人看到这些参考文献都会导致民谣错误。

举个例子:

编辑:我之前引用的例子不正确。


std::pair::operator==的文件表明,这两种元素都经过了平等性测试。std::pair::operator<的文件表明,只有当第一个元素相等时,才考虑第二个元素。

两种情况下都会出现"相等"一词。然而,只有在第一种情况下,它才真正意味着T::operator==。在第二种情况下,相等意味着!(a.first


type_info的文档首先试图解释typeid,但失败了:

typeid can be applied directly to
types, in which case it returns its
information; Or to objects, in which
case it returns information on the
type of the object.

When typeid is applied to a
dereferenced pointer to an object of a
polymorphic class type (a class
declaring or inheriting a virtual
function), it considers its dynamic
type (i.e., the type of the most
derived object).

现在第二段已经和第一段不一致了。在typeid(*ptr)中,typeid应用于表达式。这是相当重要的,因为staticdynamic类型的概念只在表达式上下文中有意义,而不是对象。它还漏掉了像typeid(foo())这样的案例。

此外,第二段省略了参考文献。它们也可以具有不同于所引用对象的动态类型的静态类型。