ejemplos - c++ online
¿Qué pasa con cplusplus.com? (6)
Quizás este no sea un foro perfectamente adecuado para esta pregunta, pero permítanme intentarlo, a riesgo de que lo alejen.
Hay varias referencias para la biblioteca estándar de C ++, incluido el invaluable estándar ISO, MSDN , IBM , cppreference y cplusplus . Personalmente, cuando escribo C ++ necesito una referencia que tenga acceso aleatorio rápido, tiempos de carga cortos y ejemplos de uso, y he descubierto que cplusplus.com es bastante útil. Sin embargo, he estado escuchando opiniones negativas sobre ese sitio frecuentemente aquí en SO, por lo que me gustaría obtener información específica:
¿Cuáles son los errores, conceptos erróneos o malos consejos dados por cplusplus.com? ¿Cuáles son los riesgos de usarlo para tomar decisiones de codificación?
Permítanme agregar este punto: quiero poder responder preguntas aquí en SO con citas precisas del estándar, y por lo tanto me gustaría publicar enlaces de uso inmediato, y cplusplus.com hubiera sido mi sitio de elección si no fuera por este problema.
Actualización: Hubo muchas respuestas excelentes, y he cambiado seriamente mi punto de vista en cplusplus.com. Me gustaría enumerar algunos resultados de elección aquí; siéntase libre de sugerir más (y siga publicando respuestas).
A partir del 29 de junio de 2011:
- Descripción incorrecta de algunos algoritmos (por ejemplo,
remove
). - La información sobre el comportamiento de las funciones a veces es incorrecta (
atoi
), no menciona casos especiales (strncpy
) u omite información vital (invalidación del iterador). - Los ejemplos contienen código obsoleto (estilo #include).
- La terminología inexacta está perjudicando a los alumnos y a la comunidad en general ("STL", "compilador" y "cadena de herramientas").
- Descripción incorrecta y engañosa de la palabra clave
typeid
.
La documentación de std::pair<T1,T2>::operator==
dice que se prueba la igualdad de ambos elementos. La documentación de std::pair<T1,T2>::operator<
dice que los segundos elementos se consideran solo si los primeros elementos son iguales.
La palabra "igual" aparece en ambos casos. Sin embargo, solo en el primer caso realmente significa T::operator==
. En el segundo caso, !(a.first<b.first || b.first<a.first)
medios iguales !(a.first<b.first || b.first<a.first)
La documentación de type_info
intenta explicar primero typeid
, pero falla:
typeid se puede aplicar directamente a los tipos, en cuyo caso devuelve su información; O a los objetos, en cuyo caso devuelve información sobre el tipo de objeto.
Cuando se aplica typeid a un puntero desreferenciado a un objeto de un tipo de clase polimórfica (una clase que declara o hereda una función virtual), considera su tipo dinámico (es decir, el tipo del objeto más derivado).
Ahora el segundo párrafo ya no está de acuerdo con el primero. En typeid(*ptr)
, typeid
se aplica a una expresión. Esto es bastante esencial, ya que la noción de tipos static
y dynamic
solo tiene sentido en el contexto de la expresión, no de los objetos. También falla en casos como typeid(foo())
.
Además, el segundo párrafo omite referencias. Ellos también pueden tener tipos estáticos diferentes del tipo dinámico del objeto al que hacen referencia.
Voy a ofrecer una opinión ligeramente en contra. Hay mucha información buena en cplusplus.com. Elija a la muerte, y sí, por supuesto que tiene sus problemas, pero ¿qué sitio no? Ciertamente no este sitio . Las personas que viven en casas de vidrio no deben arrojar piedras. Aquí también hay mucha desinformación. Hay respuestas aceptadas que son completamente erróneas, respuestas downvoted (¡algunas negativas!) Que son correctas.
Un problema con cplusplus.com es que es un sitio cerrado; Lo mismo ocurre con la mayoría de los otros sitios de referencia mencionados. Esto va contra la corriente de un sitio desarrollado por la comunidad como . La adquisición de la capacidad de realizar ediciones de confianza no lleva demasiado tiempo, e incluso los novatos más nuevos pueden hacer sugerencias para mejorar. Compare eso con cplusplus.com. Eres un novato perpetuo si no estás en su personal. Incluso si usted es un miembro clave de WG21, debe revisar su mecanismo de informe de correo electrónico si ve un error en algún lugar de ese sitio. ¡Anatema!
Una solución sería para nosotros en este sitio para desarrollar nuestra propia referencia de C ++. Esto tomaría bastante trabajo. Tendríamos que tener cuidado de no ser demasiado pedantes / demasiado técnicos; es obvio que cplusplus.com emplea al menos algunos editores técnicos que mantienen a raya a los pedantes. Tendríamos que mantener la información bien organizada; las preguntas frecuentes aquí no están bien organizadas. También tendríamos que tener mucho cuidado de no generar mucho directamente del estándar; eso es ilegal
http://www.cplusplus.com/reference/clibrary/cstring/strncpy/
No menciona que "si la copia se lleva a cabo entre objetos que se superponen, el comportamiento no está definido". (4.11.2.4 en el estándar C89. No tengo una copia a mano de C90, que es a lo que C ++ 03 realmente se refiere, pero se supone que difieren solo en cosas como la numeración de páginas).
La documentación proporcionada por cplusplus.com a menudo es incorrecta o incompleta.
Una vez que tal ejemplo es, la documentación atoi en cplusplus.com.
atoi
En la sección Retorno, no se menciona el valor de retorno 0 si no se puede realizar ninguna conversión mientras se usa la función.
cplusplus.com La sección de retorno indica "... Si el valor convertido estaría fuera del rango de valores representables por un int, causa un comportamiento indefinido".
Esto es correcto, según el estándar " Si el valor numérico de la cadena no se puede representar en int, entonces el comportamiento no está definido ".
Sin embargo, la sección no está llena, ya que no menciona 0 como valor de retorno, lo que puede ser engañoso. La frase "... no se realiza conversión y se devuelve cero". se cumple antes en el párrafo de descripción, pero es esencial tenerlo en la sección de Devolución .
Muchos de los códigos fuente de muestra que se ofrecen en cplusplus.com son incorrectos.
Muchos de los novatos que buscan estas referencias son inducidos a cometer errores de ballant.
Para citar un ejemplo:
EDITAR: El ejemplo que cité anteriormente era incorrecto.
Editar: La documentación para std::remove
se ha corregido desde que se escribió esta respuesta. Lo mismo se aplica a list::remove
.
Déjame darte un ejemplo para mostrarte cómo cpluscplus.com puede equivocarse.
Considere la función std::remove
de <algorithm>
.
El hecho es que std::remove
no elimina el elemento del contenedor. Es porque std::remove
funciona solo con un par de iteradores y no sabe nada sobre el contenedor que realmente contiene los elementos. De hecho, no es posible que std::remove
conozca el contenedor subyacente, porque no hay forma de que pueda ir desde un par de iteradores para descubrir el contenedor al que pertenecen los iteradores. Entonces std::remove
realmente no elimina los elementos, simplemente porque no puede . La única manera de eliminar realmente un elemento de un contenedor es invocar una función de miembro en ese contenedor.
Por lo tanto, si desea eliminar los elementos, utilice Erase-Remove Idiom :
v.erase(std::remove(v.begin(), v.end(), 10), v.end());
Pero cplusplus.com
brinda información incorrecta sobre std::remove
. Dice
Tenga en cuenta que esta función no altera los elementos más allá del nuevo final, que mantienen sus valores anteriores y aún son accesibles .
que no es correcto El iterador en el rango [new_end, old_end)
sigue siendo eliminable, pero eso NO significa que conserven los valores anteriores y aún estén accesibles. Ellos no están especificados.
Del mismo modo, cplusplus.com
proporciona información incorrecta sobre list::remove
también. Dice ,
Observe que existe una función de algoritmo global, eliminar, con un comportamiento similar pero que funciona entre dos iteradores.
lo cual es completamente incorrecto La eliminación global a saber std::remove
no es similar a list::remove
, ya que vimos que el primero NO elimina realmente los elementos del contenedor porque no puede , mientras que el último (la función miembro) realmente elimina los elementos porque puede
Esta respuesta se copia de mi otra respuesta en el siguiente tema, con pequeñas modificaciones:
Nota: Desde que encontré esto recientemente cuando estaba respondiendo en el tema anterior, lo recuerdo. Hay muchos errores que he encontrado en los últimos dos años, que no recuerdo. Podría agregar algunos más más tarde, si me vuelvo a encontrar.