-2

I just started learning C++ as an additional language and came across the problem mentioned in the title. Here's the code I started out with:

#include "HelloWorldWriter.h"
#include <iostream>

using namespace std;

int HelloWorldWriter::getNumberOfRepetitions() {
    cout << "Enter number of Hello Worlds: ";
    int repetitions = 0;
    if(cin >> repetitions){
        if(repetitions > 0){
            return repetitions;
        }
    } else{
        return 0;
    }
}

...

I assumed that cin >> repetitions would store the user input value into repetitions and return true if the user has entered something that could be parsed into an integer, and false otherwise. I then tried to assign the result of cin >> repetitions to a boolean, but it produced an error, saying "Types bool and istream are not compatible". I then tried the following assignment:

istream inputSuccessful = cin >> repetitions;

This however produced an error, saying "basic_istream::basic_istream(const basic_istream &) is deleted".

I have the following questions now:

1) When using cin >> someInt (with integer someInt as a target/argument), what behaviour (value in target variable, return value, behaviour during the next call of that operator,...) should you expect, if the user enters a word with no leading numbers (i.e. that can't be parsed into an integer)?

2) How would you save the result of cin >> someInt in a variable? What type would it have to be? How does that value relate to boolean expressions?

sildave94
  • 11
  • 2
  • for 2) you dont need to save it, because it just returns a reference to `cin` that you never need to save. The only usefullness (in this particular case) is that you can chain calls to `>>` like in `std::cin >> a >> b;` – 463035818_is_not_an_ai Sep 06 '17 at 11:21
  • Related: [Why istream object can be used as a bool expression?](https://stackoverflow.com/questions/8117566/why-istream-object-can-be-used-as-a-bool-expression). See also: [`std::basic_istream::operator>>`](http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt) and [`std::basic_ios::operator bool`](http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool) – Ivan Aksamentov - Drop Sep 06 '17 at 11:30

1 Answers1

2

This declaration

istream inputSuccessful = cin >> repetitions;

calls for a copy of cin into inputSuccessful. Copy constructor is deleted for streams, hence the error that you get. However, copying or taking a reference of cin is pointless, because whatever you could do with a reference you could also do with cin directly.

You should make your variable bool instead:

bool inputSuccessful(cin >> repetitions);

Now inputSuccessful would contain true if reading repetitions was successful, and false otherwise. The way this works is described in this Q&A.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Great, thanks! Assigning it to a `bool` doesn't work, it says "Types bool and istream are not compatible". However, as you suggested, I was able to just use `cin` as the condition. Can you explain to me what happens there, behind the scenes, in `cin`? Is there a specific method that is called whenever any object is used as a boolean condition? – sildave94 Sep 06 '17 at 11:31
  • It would look nicer with `static_cast`. As a side effect, it would also look more readable with parentheses (I can never remember operator precedence). – Ivan Aksamentov - Drop Sep 06 '17 at 11:32
  • @sildave94 Assignment syntax does not work, but initialization syntax does ([demo](https://ideone.com/myiwf5)). What happens behind the scenes depends on the version of C++. It is very well explained in the Q&A that I linked at the end of the answer (there is an implicit conversion operator defined for `istream`). – Sergey Kalinichenko Sep 06 '17 at 11:38
  • @Drop I think parenthesized initialization is even better than a static cast, and (obviously) parentheses are included :-) – Sergey Kalinichenko Sep 06 '17 at 11:39