Что случилось с cplusplus.com?
Возможно, это не совсем подходящий форум для этого вопроса, но позвольте мне сделать это, рискуя быть отодвинутым.
Существует несколько ссылок на стандартную библиотеку С++, включая бесценный стандарт ISO, MSDN, IBM, cppreference и cplusplus. Лично, при написании С++ мне нужна ссылка, которая имеет быстрый случайный доступ, короткие времена загрузки и примеры использования, и я нахожу cplusplus.com довольно полезным. Тем не менее, я часто слышал негативные отзывы об этом веб-сайте здесь, поэтому я хотел бы уточнить:
Каковы ошибки, неправильные представления или плохие советы, даваемые cplusplus.com? Каковы риски его использования для принятия решений по кодированию?
Позвольте мне добавить этот момент: я хочу быть в состоянии ответить на вопросы здесь о SO с точными цитатами стандарта, и поэтому я бы хотел опубликовать ссылки, пригодные для немедленного использования, и cplusplus.com был бы моим сайтом выбора это не для этой проблемы.
Обновление: Было много замечательных ответов, и я серьезно изменил свой взгляд на cplusplus.com. Здесь я бы хотел привести несколько результатов. не стесняйтесь предлагать больше (и продолжайте отправлять ответы).
По состоянию на 29 июня 2011 года:
- Неправильное описание некоторых алгоритмов (например,
remove
).
- Информация о поведении функций иногда некорректна (
atoi
), не упоминается о специальных случаях (strncpy
) или опускается важная информация (недействительность итератора).
- Примеры содержат устаревший код (стиль #include).
- Неточная терминология оказывает плохую услугу учащимся и общему сообществу ( "STL", "компилятор" и "toolchain" ).
- Неверное и вводящее в заблуждение описание ключевого слова
typeid
.
Ответы
Ответ 1
Изменить: Документация для std::remove
исправлена с момента написания этого ответа. То же самое относится к list::remove
.
Позвольте мне привести вам пример, чтобы показать вам, как cpluscplus.com может ошибиться.
Рассмотрим функцию std::remove
из <algorithm>
.
Дело в том, что std::remove
не удаляет элемент из контейнера. Потому что std::remove
работает только с парой итераторов и ничего не знает о контейнере, который фактически содержит элементы. На самом деле, std::remove
не может знать базовый контейнер, потому что нет пути, который он может исходить от пары итераторов, чтобы узнать о контейнере, к которому принадлежат итераторы. Таким образом, std::remove
действительно не удаляет элементы, просто потому, что он не может. Единственный способ фактически удалить элемент из контейнера - вызвать функцию-член в этом контейнере.
Итак, если вы хотите удалить элементы, используйте Erase-Remove Idiom:
v.erase(std::remove(v.begin(), v.end(), 10), v.end());
Но cplusplus.com
дает неверную информацию о std::remove
. Он говорит
Обратите внимание, что эта функция не изменяет элементы за новым концом, которые сохраняют свои старые значения и все еще доступны.
что неверно. Итератор в диапазоне [new_end, old_end)
по-прежнему является разыменованным, но это НЕ означает, что они сохраняют старые значения и все еще доступны. Они не указаны.
Аналогично, cplusplus.com
дает неверную информацию о list::remove
. Он говорит,
Обратите внимание, что функция глобального алгоритма remove, существует с аналогичным поведением, но работает между двумя итераторами.
что совершенно неверно. Глобальное удаление, а именно std::remove
не похоже на list::remove
, поскольку мы видели, что предыдущий НЕ удаляет элементы из контейнера, потому что он не может, тогда как последний (функция-член) действительно удаляет элементы, потому что это возможно.
Этот ответ копируется из моего другого ответа в следующем разделе с небольшими изменениями:
Примечание: Поскольку я натолкнулся на это недавно, когда я отвечал в вышеупомянутой теме, я это помню. За последние два года я столкнулся с множеством ошибок, о которых я не помню. Я мог бы добавить несколько позже, если снова встречу.
Ответ 2
Я собираюсь немного подумать об этом. На cplusplus.com есть много хорошей информации. Выбирайте его до смерти, и да, конечно, у него есть свои проблемы, но на каком сайте нет? Конечно, не этот сайт. Люди, которые живут в стеклянных домах, не должны бросать камни. Здесь также много дезинформации. Есть принятые ответы, которые ошибочны, нисходящие ответы (некоторые отрицательные!), Которые точны на правильном.
Одна проблема с cplusplus.com заключается в том, что это закрытый сайт; то же самое касается большинства других упомянутых ссылочных сайтов. Это противоречит текстуре сайта, разработанного сообществом, такого как Stack Overflow. Приобретение возможности делать доверенные изменения не так долго, и даже новейшие новички могут легко внести предложения по улучшению. Сравните это с cplusplus.com. Вы вечный новичок, если не находитесь в их штате. Даже если вы являетесь ключевым участником WG21, вам нужно пройти через механизм отправки сообщений электронной почты, если вы видите ошибку где-то на этом сайте. Анафема!
Решение было бы для нас на этом сайте разработать нашу собственную ссылку на С++. Это займет немало работы. Мы должны быть осторожны, чтобы не быть слишком педантичными/слишком техничными; очевидно, что в cplusplus.com работают как минимум несколько технических редакторов, которые держат педантов в страхе. Мы должны держать эту информацию хорошо организованной; FAQ здесь не очень хорошо организованы. Мы также должны быть очень осторожны, чтобы не изливаться слишком сильно из стандарта; что незаконно.
Ответ 3
http://www.cplusplus.com/reference/clibrary/cstring/strncpy/
Нельзя сказать, что "Если копирование происходит между перекрывающимися объектами, поведение undefined". (4.11.2.4 в стандарте C89. У меня нет копии от C90, на что на самом деле ссылается С++ 03, но они должны различаться только в таких вещах, как нумерация страниц.)
Ответ 4
Документация, предоставленная cplusplus.com, часто является неправильной или неполной.
Как только такой пример, atoi
документация на cplusplus.com.
atoi
В разделе "Возврат" нет упоминания о возвращаемом значении 0, если при использовании функции нельзя выполнить преобразование.
cplusplus.com Возвращает раздел: "... Если преобразованное значение будет вне диапазона значений, представляемых с помощью int, оно вызывает поведение undefined."
Это правильно, согласно стандарту "Если числовое значение строки не может быть представлено в int, тогда поведение undefined".
Однако раздел не заполнен, так как он не упоминает 0 как возвращаемое значение, которое может вводить в заблуждение. Фраза "... преобразование не выполняется, и возвращается ноль". выполняется в параграфе описания, но важно иметь его в разделе Return.
Многие примеры исходных кодов, приведенные на cplusplus.com, неверны.
Многие из новичков, которые смотрят на эти ссылки, приводят к ошибкам балласта.
Чтобы привести пример:
EDIT: Пример, приведенный выше, был неверным.
Ответ 5
Документация для type_info
сначала пытается объяснить typeid
, но не выполняется:
typeid может применяться непосредственно к типов, и в этом случае он возвращает свои Информация; Или объектам, в которых случае он возвращает информацию о тип объекта.
Когда typeid применяется к разыменованный указатель на объект тип полиморфного класса (класс объявление или наследование виртуального функция), он считает свою динамику типа (т.е. типа наиболее производный объект).
Теперь второй абзац уже не согласен с первым. В typeid(*ptr)
к выражению применяется typeid
. Это довольно важно, поскольку понятие типов static
и dynamic
имеет смысл только в контексте выражения, а не объектов. Он также пропускает такие случаи, как typeid(foo())
.
Кроме того, второй абзац опускает ссылки. Они также могут иметь статические типы, отличные от динамического типа объекта, который они ссылаются.
Ответ 6
В документации std::pair<T1,T2>::operator==
говорится, что оба элемента проверяются на равенство. В документации std::pair<T1,T2>::operator<
говорится, что второй элемент рассматривается только в том случае, если первые элементы равны.
В обоих случаях появляется слово "equal". Тем не менее, только в первом случае это действительно означает T::operator==
. Во втором случае равным означает !(a.first<b.first || b.first<a.first)