Що не так з cplusplus.com?


200

Це, мабуть, не ідеально підходящий форум для цього питання, але дозвольте мені спробувати, ризикуючи перенестись.

Існує кілька посилань на стандартну бібліотеку C ++, включаючи неоціненний стандарт ISO, MSDN , IBM , cppreference та cplusplus . Особисто мені під час написання C ++ потрібна довідка, яка має швидкий випадковий доступ, короткий час завантаження та приклади використання, і я вважаю cplusplus.com досить корисною. Однак я часто чую негативні думки щодо цього веб-сайту тут, тому я хочу уточнити:

Які помилки, помилки чи неправильні поради, які дає cplusplus.com? Які ризики використовувати його для прийняття рішень щодо кодування?

Додам до цього моменту: я хочу мати змогу відповідати на запитання тут на SO точними цитатами стандарту, і, таким чином, я хотів би розміщувати негайно використані посилання, і cplusplus.com був би моїм сайтом на вибір, якби не він ця проблема.


62
Чому голоси? Це цілком справедливе питання. Якщо вам потрібна довідка, ви хочете довірене джерело. Я також чув скарги на cplusplus.com, де я можу отримати швидке посилання на стандартну бібліотеку, і як таке, це цікаво.
Xeo

48
@Olafur: Я не хочу думки, я хочу конкретні списки помилок на цьому сайті. Якщо таких немає, я хочу використати це питання, щоб розвіяти критику в майбутньому.
Керрек СБ

4
@ Ólafur Waage: можливо. Але щодо точності / правдивості вмісту цього веб-сайту можна зробити абсолютно об'єктивні моменти.
Даніель Слоуф

14
Ми вже на першій сторінці для "cplusplus.com" в Google. Вражає те, як швидко питання запитання піднімаються на пошукові рейтинги.
Гонки легкості по орбіті

5
Я думаю, що це справедливо - враховуючи, наскільки високо це питання займає пошуки "cplusplus" - зазначити, що, оскільки це питання було задано, на cplusplus.com було внесено ряд виправлень. Насправді три найкращі відповіді, які вказують на помилки, вже не відповідають дійсності.
Марк Н

Відповіді:


72

Редагувати: Документація на std::removeвиправлена ​​з моменту написання цієї відповіді. Те ж саме стосується і list::remove.

Дозвольте навести приклад, щоб показати вам, як cpluscplus.com може помилитися.

Розглянемо std::removeфункцію від <algorithm>.

Справа в тому, що std::removeвін не видаляє предмет з контейнера. Це тому, що std::removeпрацює лише з парою ітераторів і нічого не знає про контейнер, який фактично містить елементи. Насправді std::removeзнати базовий контейнер неможливо , оскільки немає можливості перейти від пари ітераторів, щоб дізнатися про контейнер, до якого належать ітератори. Тож std::removeнасправді не видаляйте елементи просто тому, що вони не можуть . Єдиний спосіб фактично видалити елемент з контейнера - це викликати функцію члена на цьому контейнері.

Тож якщо ви хочете видалити елементи, тоді використовуйте Стерти-видалити ідіому :

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

Але cplusplus.comдає неправильну інформацію про std::remove. Він говорить

Зауважте, що ця функція не змінює елементи минулого нового кінця, які зберігають свої старі значення та все ще доступні .

що невірно. Ітератор у діапазоні [new_end, old_end)все ще зберігається, але це НЕ означає, що вони зберігають старі значення та все ще доступні. Вони не визначені.


Аналогічно cplusplus.comдає і невірну інформацію про list::remove. Це говорить ,

Зауважте, що функція видалення глобального алгоритму існує з подібною поведінкою, але працює між двома ітераторами.

що абсолютно неправильно. Глобальне видалення std::remove- це не схоже на те list::remove, як ми побачили, що перший НЕ дійсно видаляє елементи з контейнера, оскільки не може , тоді як другий (функція-член) дійсно видаляє елементи, оскільки може .

Ця відповідь скопійована з моєї іншої відповіді в наступній темі, з незначними змінами:

Примітка: Оскільки я нещодавно натрапив на це, коли відповідав у вищевказаній темі, я пам’ятаю це. Є багато помилок, з якими я стикався протягом останніх двох років, яких я не пам’ятаю. Я можу додати ще декілька пізніше, якщо я знову зустрінусь.


1
+1: чи є набагато більше тих неправильних тверджень на цьому сайті?
Клаїм

4
@ Олександр: list::removeвидаляє елементи з контейнера. Але std::removeНЕ виймає елементи з контейнера. Я не можу сказати, що їх поведінка "схожа".
Наваз

3
Приємний улов! Це дуже хороший приклад того, що я шукаю.
Керрек СБ

3
"Подібний" є дискусійним, оскільки це питання думки, схожі чи ні дві різні операції. Також дискутують, чи слід пропонувати думку cplusplus.com, замасковану під документацію. Але в будь-якому випадку "зберігати свої старі значення" - це невиправдана помилка, вона просто показує, що опис cplusplus не базувався на стандарті.
Стів Джессоп

5
@Steve: Ви сказали "Similar" is debateable. Якщо це слово similarє дискусійним, воно дуже говорить про те, що це слово не є правильним словом і його слід уникати при поясненні поведінки std::removeта list::remove, оскільки пояснення повинно бути максимально чітким, воно не повинно вимагати іншого пояснення.
Наваз

38

Я збираюся запропонувати свою думку трохи протилежну. На сайті cplusplus.com є багато хорошої інформації. Вибирайте це до смерті, і так, звичайно, у нього є проблеми, але який сайт не має? Звичайно, не цей сайт . Люди, які живуть у скляних будиночках, не повинні кидати каміння. Тут також багато дезінформації. Є прийняті відповіді, які є невірними неправильними, негативними відповідями (деякими негативними!), Які є правильними.

Одне з питань cplusplus.com полягає в тому, що це закритий сайт; те саме стосується більшості інших згаданих довідкових сайтів. Це суперечить зерну сайту, розробленого громадою, такого як Stack Overflow. Набуття здатності вносити довірені зміни не потребуватиме багато часу, і навіть найновіші новачки можуть легко вносити пропозиції щодо вдосконалення. Порівняйте це з cplusplus.com. Ви вічний новачок, якщо ви не в їх штаті. Навіть якщо ви є ключовим членом WG21, вам доведеться пройти механізм звітування електронної пошти, якщо ви побачите помилку десь на цьому сайті. Анатема!

На цьому веб-сайті було б рішення розробити власну довідку C ++. Це займе зовсім небагато роботи. Ми повинні бути обережними, щоб не бути занадто педантичними / занадто технічними; очевидно, що на cplusplus.com працює принаймні кілька технічних редакторів, які тримають педантів у страху. Ми б мали зберігати інформацію добре організованою; Поширені запитання тут недостатньо організовані. Нам також слід бути дуже обережними, щоб не викинути занадто багато прямо зі стандарту; це незаконно.


7
Раніше я часто відвідував старий cppreference.com, але тепер вони переробили його у щось wiki-ish (це відкрито для редагування усіма?) ... і мені це вже не дуже подобається. Мені важко побачити важливу інформацію. Просто не вистачає негайного задоволення, яке я отримую від cplusplus.com. Я думаю.
Керрек СБ

14
Ого! Я бачу саме протилежне. Я переставав часто відвідувати старий cppreference.com, тому що мені було важко переходити і погано написаний. Новий сайт cppreference.com є веб-сайтом без реклами, який робить саме те, що я запропонував у своєму останньому абзаці.
Девід Хаммен

1
Можливо, це був лише я, спробую ще раз. Я думаю , що я хотів би подивитися деякі <thread>або <atomic>речі , і тільки що отримав «будь ласка , напишіть цю сторінку» , так що я здався. Дозвольте ще раз перевірити! О, підтримка C ++ 0x, звичайно, була б величезним бонусом!
Керрек СБ

10
"Люди, які живуть у скляних будиночках, не повинні кидати каміння". ТАК не стверджує, що є (частково) посиланням на бібліотеку для C ++, як це робить cplusplus.com/reference . Коли люди пред'являють претензії тут, вони цитують стандарт, щоб їх створити резервні копії, або якщо вони не стають, тоді хтось інший приходить і заповнює. Якщо вони помиляються, ви можете побачити їх роботу. Якщо cplusplus.com помиляється, ви просто написали код, який не зможе виконати деякі C ++ реалізації, крім того, який автор використовував для створення "детального опису його елементів". Проблема полягає в тому, що cplusplus.com неофіційний, але написаний, щоб виглядати формально.
Стів Джессоп

4
Так неформально, і написано, щоб виглядати неформально. Тепер, якщо cplusplus.com не призначений для точної документації / довідкового матеріалу, і я десь пропустив відмову від відповідальності, тоді досить припустимо, що будь-які камені будуть кинуті людям, які використовують саме це, а не сам сайт. Але справа в тому, що те, що cplusplus.com говорить щось про функцію C ++, не означає, що це правда, і варто знати, що якщо ви плануєте використовувати її як швидку посилання. Я використовую його для пошуку підписів функцій, але ніколи не вирішувати точну точку відповідності мого коду чи ні.
Стів Джессоп

14

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

Не зазначається, що "Якщо копіювання відбувається між об'єктами, які перекриваються, поведінка не визначена". (4.11.2.4 у стандарті C89. У мене немає копії C90 в руці, до чого насправді посилається C ++ 03, але вони повинні відрізнятися лише в таких речах, як нумерація сторінок.)


Ах, стара бібліотека С ... приємно.
Керрек СБ

6
Вони згадують destination and source shall not overlap.
Снайпер

2
@Sniper "не перетинається" - це не те саме, що "поведінка не визначена". Ваш коментар насправді висвітлює один із найтонших, повсюдних збоїв cplusplus.com - це звучить правильно, але це не правильно.
Ендрю Генле

@Sniper: Я думаю, напевно, це не говорило про те, що, коли я зробив цю відповідь у 2011 році, я вважав би, що "не перекриватиметься" як достатня обмеження в роботі.
Стів Джессоп

9

Документація, надана cplusplus.com, часто є невірною або неповною.

Як тільки такий приклад є, atoiдокументація на cplusplus.com.

atoi
У розділі Return не згадується про 0 повернене значення, якщо перетворення під час використання функції не може бути здійснено.

У розділі " Повернення cplusplus.com " зазначено "... Якщо перетворене значення виходитиме за межі інтерпретабельних значень за допомогою int, це спричиняє не визначене поведінку."

Це правильно, згідно зі стандартом " Якщо числове значення рядка не можна представити в int, тоді поведінка не визначена ".

Однак розділ не є повним, оскільки він не зазначає 0 як повернене значення, що може ввести в оману. Фраза "... конверсія не виконується і нуль не повертається". зустрічається раніше в пункті опису, але важливо мати його у розділі " Повернення ".

Багато зразків вихідних кодів, наведених на cplusplus.com, є невірними.
Багато хто з новачків, які шукають ці посилання, призводять до помилок.

Навести приклад:

EDIT: Приклад, який я наводив раніше, був невірним.


5
Можливо балант -> кричущий? Однак ballant - це французьке слово для "звисання", яке може бути помилковим для помилок, що стосуються покажчиків.
хардмат

Прочитайте, що приклад ітератора ... немає невизначеної поведінки.
Dennis Zickefoose

1
Ви заявили, що "багато зразків вихідних кодів, наведених на cplusplus.com, є невірними." а потім вилучив приклад із зазначенням "Приклад, який я наводив раніше, був невірним". - Чому ви прибрали приклад? :)
користувач2962533

Відповідно до цього сайту, випадок, який ви описуєте, призводить до невизначеного типу повернення, а не до визначеної поведінки. en.cppreference.com/w/cpp/string/byte/atoi ; однак, схоже, Cplusplus.com оновив свою документацію, щоб відповідати тому, що ви говорите. Очевидно, вони відповідають на прохання громади про виправлення. Тим не менш, я не впевнений, який веб-сайт є найбільш правильним, оскільки ці два питання дуже різняться.
shawn1874

Минуло 9 років з часу опублікування цієї відповіді. Чи все ще вважається, що Cplusplus.com містить значну кількість невірної або неповної інформації?
Тайлер Шеллберг

3

Документація для type_infoспроб спочатку пояснити typeid, але не вдається:

typeid може застосовуватися безпосередньо до типів, і в цьому випадку він повертає свою інформацію; Або об'єктам, і в цьому випадку він повертає інформацію про тип об'єкта.

Коли typeid застосовується до відміненого вказівника на об'єкт поліморфного типу класу (клас, який декларує або успадковує віртуальну функцію), він враховує його динамічний тип (тобто тип найбільш похідного об'єкта).

Тепер другий абзац вже не погоджується з першим. В typeid(*ptr), typeidзастосовується до виразу. Це досить важливо, оскільки поняття staticі dynamicтипи мають сенс лише в контексті вираження, а не в об'єктах. Він також пропускає подібні випадки typeid(foo()).

Крім того, другий абзац не містить посилань. Вони також можуть мати статичні типи, відмінні від динамічного типу об'єкта, на який вони посилаються.


Дуже приємно - питання RTTI виникають на SO із передбачуваною регулярністю. Добре знати, що не посилатися.
Керрек СБ

3

Документація std::pair<T1,T2>::operator==говорить, що обидва елементи перевіряються на рівність. Документація std::pair<T1,T2>::operator<говорить, що другі елементи розглядаються лише за умови, що перші елементи рівні.

Слово "рівний" з'являється в обох випадках. І все-таки лише в першому випадку це дійсно означає T::operator==. У другому випадку рівні засоби!(a.first<b.first || b.first<a.first)


Це обов'язково, чи бібліотека може безкоштовно використовуватись operator==у другому випадку, якщо оператор доступний?
Керрек СБ

1
Обов’язкові. Стандарт C ++ не змішується operator==і operator<.
MSalters
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.