Что случилось с 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)