usar - tipo bool c++
¿Cómo puede std:: cin devolver un bool y sí mismo al mismo tiempo? (4)
[...] entonces eso debe significar que el operador devuelve un bool [...]
No, devuelve std::cin
(por referencia). La razón por la que while(std::cin >> value);
funciona es porque std::istream
(que es el tipo de std::cin
) tiene un operador de conversión .
Un operador de conversión básicamente permite que una clase sea implícitamente (si no está marcada explicit
) convertida a un tipo dado. En este caso, std::istream
define su operator bool
para devolver si se produjo un error (típicamente, error de failbit
);
[std::ios_base::operator bool()]
Devuelve
true
si la secuencia no tiene errores y está lista para operaciones de E / S. Específicamente, devuelve!fail()
.
explicit operator bool() const;
Tenga en cuenta que aunque el operador sea explicit
(lo que no debería permitir conversiones implícitas como if (std::cin);
), el calificador se ignora cuando se usa en un contexto que requiere un bool
, como if
, while
loops y for
loops. Esas son excepciones, no reglas.
Aquí hay un ejemplo:
if (std::cin >> value); //OK, a ''std::istream'' can be converted into a ''bool'', which
//therefore happens implicitly, without the need to cast it:
if (static_cast<bool>(std::cin >> value)); //Unnecessary
bool b = std::cin >> value; //Error!! ''operator bool'' is marked explicit (see above), so
//we have to call it explicitly:
bool b = static_cast<bool>(std::cin >> value); //OK, ''operator bool'' is called explicitly
Estoy leyendo un libro en C ++ que dice que si uso el operador >> devuelve el objeto en el lado izquierdo del operador, así que en este ejemplo
std::cin >> value1;
el código devuelve std::cin
.
Pero si hago esto
while(std::cin >> value1)
Mi código estará en el bucle hasta que haya un error std::cin
lo que significa que el operador devuelve un bool
que es verdadero cuando std::cin
no falla y falso cuando std::cin
falla.
¿Cuál es uno es?
std::cin
es de tipo std::istream
(que es solo un typedef
de std::basic_istream<char>
)
Si ve el operator>>
sobrecargado diferente para basic_istream
, todos ellos están devolviendo una referencia a basic_istream
. Así que una cosa es aclarada de que el operator>>
aquí, no devuelve un bool
sino que devuelve " std::cin
". No verás ningún operator>>
allí devolviendo un valor bool
.
Entonces la pregunta ahora es, ¿cómo convierte el std::basic_istream
a bool
?
La respuesta es: se llama a un operador de conversión para este fin.
std::basic_istream
hereda un operator bool()
de su padre std::basic_ios
explicit operator bool() const;
que hace posible convertir un objeto std::basic_istream
en bool
. Uno puede fácilmente preguntarse si está marcado como explicit
(ver por qué se marca explicit
) y aún así se convierte implícitamente a bool
en un if
o while
.
La respuesta a esta pregunta es que if
o while
usa la conversión explícita "implícitamente". (ver esta respuesta por @R. Martinho Fernandes ). Entonces, if
, while
y for
son uno de los lugares donde esta " conversión contexual " a bool
ocurre implícitamente.
std::istream
(la clase que std::cin
es un objeto de) tiene la siguiente función miembro:
explicit operator bool() const;
Devuelve falso si el objeto está en un estado de error, y verdadero de lo contrario. Esta es la razón por la cual la construcción while(std::cin >> value1)
funciona. Antes de C ++ 11, tenía esta función no explícita en su lugar:
operator void*() const;
Lo que devolvió un puntero nulo si el objeto estaba en un estado de error, cumpliendo el mismo propósito.
Las operaciones en flujos devuelven una referencia al flujo.
Entonces, no un bool
.
Puede poner el resultado en una condición if
por el mismo motivo por el que puede hacer esto:
void* ptr = foo();
if (ptr) { /*...*/ }
Y, para el caso, esto:
int x = foo();
if (x) { /*...*/ }
Tanto ptr
como x
aquí se pueden convertir a un bool
para usar en la condición. En el caso de std::cin
, la conversión se logra mediante un operator bool()
dentro de la clase std::ostream
que fue explícitamente (juego de palabras) agregado para esta tarea exacta.