if (cin >> x) – ¿Por qué puedes usar esa condición?

9 minutos de lectura

if cin x ¿Por que puedes usar esa
Muhsin Alí

He estado usando “C++ acelerado” para aprender C++ durante el verano, y hay un concepto que parece que no entiendo bien.

Por que es

int x;
if (cin >> x){}

equivalente a

cin >> x;
if (cin){}

Mirando el código, me parece que estamos usando cin como variable. Pero, pensé que era una función. ¿Por qué podemos usar cin de esta manera cuando es x el que tiene el valor que ingresamos en nuestro teclado?

cin es un objeto de clase istream que representa el flujo de entrada estándar. corresponde a la cstdio Arroyo stdin. El operador >>la sobrecarga para flujos devuelve una referencia al mismo flujo. La secuencia en sí se puede evaluar en una condición booleana como verdadera o falsa a través de un operador de conversión.

cin proporciona extracción de secuencia formateada. La operacion
cin >> x;

donde “x” es un int fallará si se ingresa un valor no numérico. Entonces:

if(cin>>x)

regresará false si ingresa una letra en lugar de un dígito.

este sitio web en consejos y trucos usando E/S de C++ también te ayudará.

  • Lo siento, eso es demasiado técnico para mí. No me he metido en clases ni nada por el estilo. ¿Por qué usamos booleanos?

    – Muhsin Alí

    22 de julio de 2011 a las 14:53


  • @Muhsin Ali: Tratar de entender diferentes cosas con las que uno se topa es generalmente bueno cuando se aprende algo nuevo. Sin embargo, en este caso, le recomendaría que solo considere cin y cout como “magia” por ahora. Por supuesto que no son mágicos, pero se construyen utilizando una serie de técnicas bastante avanzadas. Probablemente sea mejor continuar por ahora y luego regresar una vez que haya dominado las clases, la herencia y la sobrecarga de operadores.

    –Anders Abel

    22 de julio de 2011 a las 14:59

  • @Muhsin: Porque todo eso if acepta como si la expresión es un valor booleano, un número entero o un puntero. La clase std::istream proporciona la capacidad de convertir un flujo de entrada en un valor booleano, y es este operador de conversión el que se usa para evaluar si se debe realizar la operación. if sucursal o la else rama.

    – David Hamman

    22 de julio de 2011 a las 15:02

  • @Muhsin: si a cin se le presentan datos que no puede procesar, entra en un “estado de falla”, por lo que debe verificarlo con una declaración if. Vaya al enlace que proporcioné mi última oración. Hay una muestra de código allí.

    usuario195488

    22 de julio de 2011 a las 15:03

  • @DavidHammen std::istream proporciona la capacidad de convertir un flujo de entrada en un booleano, y es este operador de conversión el que se utiliza… ¿Podría informarme sobre el operador de conversión que proporciona isteam?

    –Quazi Irfan

    14/10/2013 a las 22:39

if cin x ¿Por que puedes usar esa
david hamen

Nota: Respuesta actualizada cuatro años después del hecho para abordar tanto C++98/03 como C++11 (y posteriores).

std::cin es una instancia de un std::istream. Esa clase proporciona dos sobrecargas que pertenecen a esta pregunta.

  • operator >> lee datos de la secuencia en la variable de destino si eso es posible. Si el contenido inmediato de la transmisión no se puede traducir al tipo de la variable de destino, la transmisión se marca como no válida y la variable de destino se deja intacta. Independientemente del éxito/fracaso de la operación, el valor devuelto es una referencia a la secuencia.
  • Cualquiera operator void*() (anterior a C++ 11), que convierte la referencia de flujo en un void* puntero, o explicit operator bool() (C++11), que convierte la referencia de flujo en un valor booleano. El resultado de esta conversión es un puntero no nulo (pre-C++11) o true (C++11) si la secuencia es válida, pero el puntero nulo (anterior a C++11) o false (C++11) si la transmisión no es válida.

Un if La declaración necesita un booleano, un entero o un puntero como la cantidad a probar. El resultado de std::cin >> x es una referencia a un istream, que no es ninguno de los anteriores. Sin embargo, la clase istream tiene los operadores de conversión que se pueden utilizar para transformar el istream referencia a algo usable en un if declaración. Es el operador de conversión específico de la versión que usa el lenguaje para el if prueba. Dado que la falla de lectura marca la transmisión como inválida, el if la prueba fallará si la lectura no funcionó.

La razón de la más enrevesada operator void* miembro de conversión anterior a C++11 es que no fue hasta C++11 que el ya existente explicit La palabra clave se amplió para aplicarse tanto a los operadores de conversión como a los constructores. Un no explícito operator bool() habría presentado demasiadas oportunidades para que los programadores se pegaran un tiro en el pie. Hay problemas con operator void*() así como. El “modismo bool seguro” habría sido una solución, pero simplemente extendiendo explicit logró exactamente lo que logra el idioma bool seguro, y sin tener que usar mucha magia SFINAE.

  • no usa operator bool sino más bien operator void*, el operador bool permitiría su uso en contextos aritméticos, mientras que el operador void* lo impide, ya que void es un tipo incompleto. En la implementación del operador del compilador de MSVC, void* devuelve la dirección del objeto si no se establece un indicador de error (que no puede ser 0 y, por lo tanto, se evalúa como true en un contexto booleano) o 0 si se establece algún indicador (evaluando a booleano falso).

    – lccarrasco

    22 de julio de 2011 a las 15:35

  • De acuerdo a cplusplus.com/reference/ios/ios/operator_bool está operator void*() para C++98 y operator bool() para C++11.

    –Evgeni Sergeev

    13 de agosto de 2015 a las 4:23

  • @AbhishekMane std::cout<<(std::cin>>x); no puede compilar con un compilador compatible moderno a menos que le indique que compile contra el estándar C++98 (p. ej., --std=c++98). En todas las versiones del estándar, el valor de retorno de std::cin>>x es una referencia a la std::cin objeto, y no hay sobrecarga std::basic_ostream operator>> (const std::basic_istream&). Pre-C++11, el compilador usaría std::basic_istream::operator void*(). Esto devuelve el puntero nulo si la entrada falló, un puntero no nulo si la entrada tuvo éxito. por eso estas viendo 0 o 0x48650. (continuado)

    – David Hamman

    19 de agosto de 2021 a las 14:41


  • los void* El operador de conversión se eliminó en C++ 11 y se reemplazó con explicit operator bool(). los explicit (nueva en C++11) le dice explícitamente al compilador que no use esa conversión en std::cout<<(std::cin>>x). Esa expresión debería dar como resultado un error de compilación en un compilador compatible que compila contra las versiones C++11, C++14, C++17 o C++20 del estándar.

    – David Hamman

    19 de agosto de 2021 a las 14:44


  • @AbhishekMane En el caso de if (std::cin>>x) uno está pidiendo implícitamente una conversión a un bool. Esto funcionó en un entorno anterior a C++11 porque aunque std::istream no tenía un operator booltenía operator void*y un void* se puede convertir fácilmente en un bool. Esto funciona en un entorno C ++ 11 y más allá sin tener que escribir if (bool(std::cin>>x)) porque este es uno de los pocos lugares en C ++ 11 y más allá donde se permite una expresión que se puede “convertir contextualmente en bool”, incluso en el caso de explicit operator bool().

    – David Hamman

    19 de agosto de 2021 a las 15:02


cin es una variable (global) de tipo istreamno una función.

los istream la clase anula la >> operador para realizar la entrada y devolver una referencia al objeto en el que lo llamó (cin).

  • No devuelve objeto, devuelve referencia a objeto. ¿no es así?

    – atleta olímpico

    22 de julio de 2011 a las 14:33

  • @Olympian: No, es una instanciación.

    usuario195488

    22 de julio de 2011 a las 14:38

  • Si cin también es una variable, entonces podría escribir: x >> cin ?

    – Muhsin Alí

    22 de julio de 2011 a las 14:51


  • @Mushin: Solo si tal sobrecarga de >> existe

    – SLaks

    22 de julio de 2011 a las 14:52

  • @0A0D cplusplus.com/reference/iostream/istream/operador%3E%3E istream& operator>>(…) – es una referencia de retorno.

    – atleta olímpico

    22 de julio de 2011 a las 14:54

cin es variable en std espacio de nombres

operator>> referencia de retorno a cinpor eso puedes escribir: cin >> a >> ben lugar de cin >> a; cin >> b;

Las respuestas anteriores son informativas. Aquí solo doy un comentario extra.

std::cin es un objeto de clase istream y representa el flujo de entrada estándar (es decir, el teclado) que corresponde a stdin C ª Arroyo.

cin >> x primero leería un int del flujo de entrada estándar y lo asignaría a x. Después de eso, devuelva una referencia propia a cin. Así que el valor de retorno de la llamada a la función cin >> x es todavía cin.

Así que desde el punto de si condición, if(cin) y if(cin >> x) se parecen entre sí. El estandar Biblioteca OI define una función para la transmisión como esta (depende de la implementación):

explicit operator bool() const; // C++11

o

operator void*() const; //C++98, C++2003

De estas dos declaraciones, sabemos que emitir los tipo de corriente directa o indirectamente (a través de void* pintar a bool lo cual es obvio) a bool escribe.

Dentro de estas dos funciones, dependen de unos principios básicos. vapor io estados (campos de clase) para determinar si devuelve falso o verdadero (por void* caso, es nullptr O no).

cin es una instancia de clase istream que hereda la casting-to-bool función. ¡Así que funciona!

1646760675 350 if cin x ¿Por que puedes usar esa
Érix

porque el resultado de la expresión

cin >> x

evalúa a

cin

después de que se lea la transmisión.

if cin x ¿Por que puedes usar esa
Ryan Le

1) cin es una instancia de istreamver http://www.cplusplus.com/reference/iostream/cin/.

2) el >> operador de istream devolverá su operando izquierdo, en este caso es cinver http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/. Este operador establecerá failbit encendido si no se extrajeron caracteres de la cinen caso de que el lector haya terminado EOF por lo que no habrá más caracteres para leer.

3) A partir del 2) anterior, cuando la condición se evalúa después de la operación de lectura, if (cin >> x) debe ser como if (cin)consulte este enlace http://www.cplusplus.com/reference/ios/ios/operator_bool/ verás que, esto if el bloque devolverá:

  • Un puntero nulo si al menos uno de failbit o badbit Está establecido. Algún otro valor de lo contrario (para el estándar C ++ 98).

  • La función devuelve falso si al menos uno de estos indicadores de error está establecido y verdadero en caso contrario. (para el estándar C++11)

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad