可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This is perhaps not a perfectly suitable forum for this question, but let me give it a shot, at the risk of being moved away.
There are several references for the C++ standard library, including the invaluable ISO standard, MSDN, IBM, cppreference, and cplusplus. Personally, when writing C++ I need a reference that has quick random access, short load times and usage examples, and I've been finding cplusplus.com pretty useful. However, I've been hearing negative opinions about that website frequently here on SO, so I would like to get specific:
What are the errors, misconceptions or bad pieces of advice given by cplusplus.com? What are the risks of using it to make coding decisions?
Let me add this point: I want to be able to answer questions here on SO with accurate quotes of the standard, and thus I would like to post immediately-usable links, and cplusplus.com would have been my choice site were it not for this issue.
Update: There have been many great responses, and I have seriously changed my view on cplusplus.com. I'd like to list a few choice results here; feel free to suggest more (and keep posting answers).
As of June 29, 2011:
- Incorrect description of some algorithms (e.g.
remove
).
- Information about the behaviour of functions is sometimes incorrect (
atoi
), fails to mention special cases (strncpy
), or omits vital information (iterator invalidation).
- Examples contain deprecated code (#include style).
- Inexact terminology is doing a disservice to learners and the general community ("STL", "compiler" vs "toolchain").
- Incorrect and misleading description of the
typeid
keyword.
回答1:
Edit: Documentation for std::remove
has been fixed since this answer was written. Same thing applies to list::remove
.
Let me give you an example to show you how cpluscplus.com can get it wrong.
Consider std::remove
function from <algorithm>
.
The fact is thatstd::remove
doesn't remove the item from the container. Its because std::remove
works with a pair of iterators only and does not know anything about the container which actually contains the items. In fact, it's not possible for std::remove
to know the underlying container, because there is no way it can go from a pair of iterators to discover about the container to which the iterators belong. So std::remove
doesn't really remove the items, simply because it cannot. The only way to actually remove an item from a container is to invoke a member function on that container.
So if you want to remove the items, then use Erase-Remove Idiom:
v.erase(std::remove(v.begin(), v.end(), 10), v.end());
But cplusplus.com
gives incorrect information about std::remove
. It says
Notice that this function does not alter the elements past the new end, which keep their old values and are still accessible.
which isn't correct. The iterator in the range [new_end, old_end)
is still dereferenceable, but that does NOT mean that they keep the old values and are still accessible. They are unspecified.
Similarly, cplusplus.com
gives incorrect information about list::remove
as well. It says,
Notice that a global algorithm function, remove, exists with a similar behavior but operating between two iterators.
which is completely wrong. The global remove namely std::remove
is not similar to list::remove
, as we saw that the former does NOT really remove the items from the container because it cannot, whereas the latter (the member function) really does remove the items because it can.
This answer is copied from my another answer in the following topic, with little modification:
- STL remove doesn't work as expected?
Note: Since I came across this recently when I was replying in the above topic, I remember it. There are many errors which I've come across over the last two years, which I don't remember. I might add few more later, if I come across again.
回答2:
I'm going to offer an opinion slightly to the contrary. There is lots of good information on cplusplus.com. Pick at it to death, and yes, of course it has its problems, but what site doesn't? Certainly not this site. People who live in glass houses shouldn't throw stones. There is a lot of misinformation here, too. There are accepted answers that are flat-out wrong, downvoted answers (some negative!) that are spot-on correct.
One issue with cplusplus.com is is that it is a closed site; the same goes for most the other reference sites mentioned. This goes against the grain of a community-developed site such as Stack Overflow. Acquiring the ability to make trusted edits doesn't take all that long, and even the newest of newbies can easily make suggestions for improvement. Compare that to cplusplus.com. You are a perpetual newbie if you aren't on their staff. Even if you are a key member of WG21, you have to go through their email report mechanism if you see a bug somewhere in that site. Anathema!
A solution would be for us at this site to develop our own C++ reference. This would take quite a bit of work. We'd have to be careful not to be too pedantic / too technical; it is obvious that cplusplus.com employs at least a few technical editors who keep the pedants at bay. We'd have to keep the information well-organized; the FAQ here are not well organized. We'd also have to be very careful not to spout too much directly from the standard; that's illegal.
回答3:
http://www.cplusplus.com/reference/clibrary/cstring/strncpy/
Fails to mention that "If copying takes place between objects that overlap, the behavior is undefined." (4.11.2.4 in the C89 standard. I don't have a copy to hand of C90, which is what C++03 actually refers to, but they are supposed to differ only in stuff like page numbering.)
回答4:
The documentation given by cplusplus.com is often incorrect or incomplete.
Once such example is ,the atoi
documentation on cplusplus.com.
atoi
In Return section, there is no mentioning about 0 return value if no conversion can be performed while using the function.
cplusplus.com Return section states "...If the converted value would be out of the range of representable values by an int, it causes undefined behavior."
This is correct, as per the standard "If the numeric value of the string can't be represented in int, then the behaviour is undefined".
However the section is not full as it does not mention 0 as return value, which can be misleading. The phrase "...no conversion is performed and zero is returned." is met before in description paragraph, but it is essential to have it in Return section.
Many of the sample source codes given on cplusplus.com are incorrect.
Many of the newbies looking up to these references are led to making ballant errors.
To cite a example:
EDIT: The example I cited previously was incorrect.
回答5:
The documentation for type_info
tries to explain typeid
first, but fails:
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).
Now the second paragraph already disagrees with the first. In typeid(*ptr)
, typeid
is applied to an expression. This is rather essential, since the notion of static
and dynamic
types only makes sense in the context of expression, not objects. It also misses cases like typeid(foo())
.
Furthermore, the second paragraph omits references. They too can have static types different from the dynamic type of the object they reference.
回答6:
The documentation of std::pair<T1,T2>::operator==
says that both elements are tested for equality. The documentation of std::pair<T1,T2>::operator<
says that the second elements are considered only if the first elements are equal.
The word "equal" appears in both cases. Yet, only in the first case does it really mean T::operator==
. In the second case, equal means !(a.first<b.first || b.first<a.first)