3

ifstream offers an overload of operator>> to extract values from the next line of the stream. However, I tend to find myself doing this often:

int index;
input >> index;
arr[index] = <something>;

Is there any way to get this data into the [index] without having to create this temporary variable?

Justin
  • 21,374
  • 12
  • 83
  • 129
It'sNotALie.
  • 20,741
  • 10
  • 63
  • 99
  • Deepens on `arr` and ``. But ultimately, I'm leaning towards no simple solution. – StoryTeller - Unslander Monica Mar 30 '18 at 18:28
  • @StoryTeller arr is a simple `vector`, something is unrelated to `arr` and `index` – It'sNotALie. Mar 30 '18 at 18:29
  • Even if you get the data into the `[index]` without creating an explicit local (temporary) variable, you will still be getting an unnamed temporary variable. The compiler is able to optimize the explicit local variable quite well. I'd rather be explicit than tricky, but that's just me. – Eljay Mar 30 '18 at 18:30
  • @Justin yeah that's probably a very sensible option – It'sNotALie. Mar 30 '18 at 18:31
  • @Eljay that's true, I'm new to c++ so I assumed there might be something idiomatic to do there – It'sNotALie. Mar 30 '18 at 18:31
  • Speaking of idiomatic C++. Depending on `T`, prebuilding the entire vector with "dummy values" and then assigning could be unidiomatic in and of itself. – StoryTeller - Unslander Monica Mar 30 '18 at 18:32
  • @Eljay A one-liner function will be optimized as well as long as its implementation is visible. The issue is what OP considers more readable. – patatahooligan Mar 30 '18 at 18:32
  • @StoryTeller can you go on a bit? as I said still a bit new to c++ :) – It'sNotALie. Mar 30 '18 at 18:36
  • @It'sNotALie. - You initialize a `T` at the index after constructing it. Goes against the grain of having c'tors. It's like having a public `init()` method, a distinct anti-pattern. But that ultimately depends on `T`. I think there may be a bit of an XY element to this question. – StoryTeller - Unslander Monica Mar 30 '18 at 18:39
  • 1
    Since input can generally fail it is necessary to verify the read attempt was successful. The interface is deliberately the way it is to make testing idiomatic: `if (in >> value) { /* use value */ }`. Also, order of evaluation is undefined and something like `array[read(in)] = read(in);` is bound to do the wrong thing (your `` should better be nit a read of the same stream). – Dietmar Kühl Mar 30 '18 at 18:41
  • It would be better to check `index` is what you think it is before using it imo – Galik Mar 30 '18 at 18:58
  • @DietmarKühl In C++17, `array[read(in)] = read(in);` is guaranteed to evaluate the rhs first, so you'd have `read(in)`, then `read(in)`, then `array[...]`, then `... = ...`. https://stackoverflow.com/a/38501596/1896169 – Justin Mar 30 '18 at 19:22
  • 1
    Possible duplicate of [Are there any tricks to use std::cin to initialize a const variable?](https://stackoverflow.com/questions/12279601/are-there-any-tricks-to-use-stdcin-to-initialize-a-const-variable) – Jonathan Mee Mar 30 '18 at 19:32

2 Answers2

2

You can write a function to extract the next value from an istream:

template <typename T> // T must be DefaultConstructible
T read(std::istream& input) {
    T result;
    input >> result;
    return result;
}

Then, you could just write:

arr[read<int>(input)] = <something>;

Although you should probably write

arr.at(read<int>(input)) = <something>;

Because otherwise you open yourself up to a buffer-overflow vulnerability. If the input file had an integer out of range, you'd be writing out of bounds.

Justin
  • 21,374
  • 12
  • 83
  • 129
2

Sure, you can do this by just constructing a temporary istream_iterator for example:

arr[*istream_iterator<int>(input)] = something
Jonathan Mee
  • 35,107
  • 16
  • 95
  • 241
  • I've just discovered what I'd consider a duplicate of this question which didn't have this answer so [I've added this answer there as well](https://stackoverflow.com/a/49580321/2642059) and voted to dupe this question. I've beefed up my answer over there if anyone would care to go check it out. – Jonathan Mee Mar 30 '18 at 19:34