if (cin >> x) – Por que você pode usar essa condição?

Eu tenho usado o “Accelerated C ++” para aprender C ++ durante o verão, e há um conceito que parece não entender corretamente.

Porque é

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

equivalente a

 cin >> x; if (cin){} 

Ao olhar para o código, parece-me que estamos usando o cin como uma variável. Mas achei que fosse uma function. Por que podemos usar o cin dessa forma quando é o x que tem o valor que inserimos em nosso teclado?

cin é um object da class istream que representa o stream de input padrão. Corresponde ao stdin stream do cstdio . O operador >> overload para streams retorna uma referência ao mesmo stream. O stream em si pode ser avaliado em uma condição booleana como verdadeiro ou falso por meio de um operador de conversão.

cin fornece extração de stream formatado. A operação cin >> x;

onde “x” é um int falhará se um valor não numérico for inserido. Assim:

 if(cin>>x) 

retornará false se você inserir uma letra em vez de um dígito.

Este site sobre dicas e truques usando C ++ I / O irá ajudá-lo também.

Nota: Resposta atualizada quatro anos após o fato de abordar o C ++ 98/03 e C ++ 11 (e além).

std::cin é um exemplo de std::istream . Essa class fornece duas sobrecargas que pertencem a essa questão.

  • operator >> lê os dados do stream na variável de destino, se isso for possível. Se o conteúdo imediato do stream não puder ser convertido no tipo da variável de destino, o stream será marcado como inválido e a variável de destino será deixada intacta. Independentemente do sucesso / falha da operação, o valor de retorno é uma referência ao stream.
  • Qualquer operator void*() (pre-C ++ 11), que converte a referência de stream em um ponteiro void* , ou explicit operator bool() (C ++ 11), que converte a referência de stream em booleano. O resultado dessa conversão é um ponteiro não nulo (pré-C ++ 11) ou true (C ++ 11) se o stream for válido, mas o ponteiro nulo (pré-C ++ 11) ou false (C + +11) se o stream não é válido.

Uma instrução if precisa de um booleano, um inteiro ou um ponteiro como a quantidade a ser testada. O resultado de std::cin >> x é uma referência a um istream , que não é nenhum dos acima. No entanto, a class istream possui esses operadores de conversão que podem ser usados ​​para transformar a referência istream em algo utilizável em uma instrução if . É o operador de conversão específico da versão que o idioma usa para o teste if . Como a falha na leitura marca o stream como inválido, o teste if falhará se a leitura não funcionar.

A razão para o membro de conversão operator void* mais complicado antes do C ++ 11 é que não foi até C ++ 11 que a palavra-chave explicit já existente foi estendida para se aplicar aos operadores de conversão, bem como aos construtores. Um operator bool() não-explícito operator bool() teria apresentado muitas oportunidades para os programadores triggersrem no próprio pé. Existem problemas com o operator void*() também. O “bool idiomático seguro” teria sido uma correção, mas simplesmente estender explicit realizou exatamente o que o idioma bool seguro consegue, e sem ter que usar muita magia SFINAE.

cin é uma variável (global) do tipo istream , não uma function.

A class istream sobrescreve o operador >> para executar a input e retornar uma referência ao object no qual você a chamou ( cin ).

cin é variável no namespace std .

operator>> return reference to cin , por causa disso você pode escrever: cin >> a >> b , em vez de cin >> a; cin >> b; cin >> a; cin >> b;

porque o resultado da expressão

 cin >> x 

avalia para

 cin 

depois que o stream é lido.

As respostas acima são informativas. Aqui eu apenas dou um comentário extra.

std::cin é um object da class istream e representa o stream de input padrão (ou seja, o teclado) que corresponde ao stdin no stream C.

cin >> x primeiro lê um int do stream de input padrão e o atribui a x . Depois disso, retorne uma auto referência a cin . Portanto, o valor de retorno da chamada de function cin >> x ainda é cin .

Então, do ponto de condição if , if(cin) e if(cin >> x) assemelham. A biblioteca IO padrão define uma function para o stream assim (depende da implementação):

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

ou

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

A partir dessas duas declarações, sabemos que elas transmitem o tipo de stream direta ou indiretamente (por meio de void* pinter para bool que é óbvio) para o tipo bool .

Dentro dessas duas funções, elas dependem de alguns status básicos de vapor de E / S (campos de class) para determinar se o retorno é falso ou verdadeiro (para o caso void* , é nullptr ou não).

cin é uma instância de class istream que herda a function de conversão para bool . Então funciona!

porque cin é um object de class, leia mais em http://www.cplusplus.com/reference/iostream/cin/ .

Como eu sei, operador sobrecarregado >> retorna um object de class istream. Há por que aqui não é diferente

1) cin é uma instância do istream , veja http://www.cplusplus.com/reference/iostream/cin/ .

2) o operador >> do istream retornará seu operando esquerdo, neste caso ele é cin , veja http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ . Este operador irá configurar o failbit se nenhum caractere for extraído do cin , caso o leitor tenha concluído o EOF para que não haja mais caracteres para leitura.

3) A partir do 2) acima, quando a condição é avaliada após a operação de leitura, if (cin >> x) deve ser como if (cin) , consulte este link http://www.cplusplus.com/reference/ ios / ios / operator_bool / você verá que este bloco se retornará:

  • Um ponteiro nulo se pelo menos um de failbit ou badbit estiver configurado. Algum outro valor diferente (para o padrão C ++ 98).

  • A function retorna false se pelo menos um desses sinalizadores de erro estiver configurado e true de outra forma. (para o padrão C ++ 11)