17

Can the following two lines be condensed into one?

int foo;
std::cin >> foo;
ayane_m
  • 962
  • 2
  • 10
  • 26

4 Answers4

25

The smart-ass answer:

int old; std::cin >> old;

The horrible answer:

int old, dummy = (std::cin >> old, 0);

The proper answer: old has to be defined with a declaration before it can be passed to operator>> as an argument. The only way to get a function call within the declaration of a variable is to place it in the initialization expression as above. The accepted way to declare a variable and read input into it is as you have written:

int old;
std::cin >> old;
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
11

You can... with

int old = (std::cin >> old, old);

but you really should not do this

6502
  • 112,025
  • 15
  • 165
  • 265
  • 1
    Ah, good point! Clever. – Joseph Mansfield Feb 16 '13 at 20:55
  • 3
    @6502 why we shouldn't do what you say?? –  Jul 19 '17 at 07:25
  • 3
    @Mohammasd • because if the `std::cin >> old` fails (i.e., returns false), then `old` is not initialized, and then reading `old` (the second part, after the comma operator) is undefined behavior. And undefined behavior is bad. – Eljay Feb 12 '19 at 13:29
  • With regards to undefined behavior, how is this example different from example a) in https://stackoverflow.com/a/1615656/2725810 that was highly up-voted? – AlwaysLearning Sep 08 '19 at 23:07
  • 2
    @AlwaysLearning: 1) unfortunately while there is some important correlation, the number of votes or the rep of the author doesn't mean an answer is correct... there's no justification for turning your brain off and just pasting from SO. 2) in the `str` example s/he is using an `std::string` that is never uninitialized (i.e. code like `int x; return x;` is undefined behavior, `std::string s; return s;` is instead ok). – 6502 Sep 09 '19 at 06:10
3

Using a function:

int inputdata()
{
    int data;
    std::cin >> data;
    return data;
}

Then:

int a=inputdata();

For data itself:

int inputdata()
{
    static bool isDataDeclared=false;
    if (isDataDeclared==true)
    {
    goto read_data;
    }
    else
    {
        isDataDeclared=true;
    }
    static int data=inputdata();
    return data;
    read_data:
    std::cin >> data;
    return data;
}
Alien
  • 52
  • 3
  • 2
    But now do it to `data` too! – Joseph Mansfield Feb 16 '13 at 20:56
  • @JosephMansfield I think, in the original question, sometimes you just want to initialize a variable to a user-input value as opposed to a system default, an undefined value or your own value which you refuse to define. For the purposes of `data` though, I feel there is no need to "do the same" to it, since it will only exist in the function's local scope for all of three lines of execution time, and perhaps if the function is marked as inline it may even be optimized away altogether. `int old = inputdata();` may end up as equivalent to `int old; std::cin >> old;` if that happens. – thegreatjedi Dec 22 '15 at 07:46
1

Maybe not for int, but for your own types:

class MyType {
    int value;
public:
    MyType(istream& is) {
        is >> *this;
    }

    friend istream& operator>>(istream& is, MyType& object);
};  

istream& operator>>(istream& is, MyType& object) {
    return is >> object.value;
}

Then you can create the type with the istream passed to the constructor:

int main() {
    istringstream iss("42");
    MyType object(iss);
}
Peter Wood
  • 23,859
  • 5
  • 60
  • 99