0

So I was thinking of simplifying this snippet

#include <bits/stdc++.h>

using namespace std;

int n;
vector<int> A;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n;
    for (int i = 0; i < n; i++) {
        int tmp;
        cin >> tmp;
        A.push_back(tmp);
    }
}

And because I have read about inserters and back_inserters recently I thought of using them right away and this is what I came up with

#include <bits/stdc++.h>

using namespace std;

int n;
vector<int> A;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n;
    for (int i = 0; i < n; i++) cin >> *back_inserter(A);
}

But for some reason the compiler spits a gigantic error message which I can't fit here so here is the first sentence only as I think it is the most relevant.

error: no match for 'operator>>' (operand types are 'std::istream' {aka 'std::basic_istream<char>'} and 'std::back_insert_iterator<std::vector<int> >')

Thanks for your help!

NOTE: before anybody comments on the use of global variables and the using namespace line, this code was intended for use only in competitive programming.

  • *this code was intended for use only in competitive programming.* -- This is not a competitive coding site. If your code is unreadable or sloppy, be prepared to have persons comment on it. – PaulMcKenzie Nov 30 '20 at 20:27
  • 1
    here you go: [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) [Why should I not `#include `?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – 463035818_is_not_an_ai Nov 30 '20 at 20:31
  • 1
    and https://stackoverflow.com/questions/484635/are-global-variables-bad ;) – 463035818_is_not_an_ai Nov 30 '20 at 20:33
  • If competitive programming encourages or tolerates sloppy and error-prone practices, I would question the value of competitive programming. – Fred Larson Dec 01 '20 at 17:49
  • To keep it short and simple, we as competitive programmers know the problems associated with global variables, include – Salman Elgamal Dec 02 '20 at 17:22
  • continuation: 6- we don't care about compilation time 7- we rely heavily on the STL so writing std:: would be hectic, we avoid name collisions instead "What is the main focus of Competitive Programming?" I hear you ask. Coming up with an algorithm and implement it with the proper data structure to solve a problem in the time and memory limits specified. Check out https://codeforces.com/ if you would like to try it out for yourself, there are problems for all levels of expertise, and I recommend it to any high school student like me planning to pursue a career in computer science. – Salman Elgamal Dec 02 '20 at 17:22

2 Answers2

3

In this case where you are just reading space separated values from the input stream until it ends, you can use std::copy to get the values from the stream. That would look like

std::copy(std::istream_iterator<int>(cin),
          std::istream_iterator<int>(),
          std::back_inserter(vector_name));
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Thanks very much, but for the sake of simplicity I have removed the rest of the code, but more cin statement where present after the snippet above, is there a way to make the above code work? Thanks again for your fast reply! – Salman Elgamal Nov 30 '20 at 20:39
  • @SalmanElgamal I know of no way to use `cin >> something` to add to a vector where `something` is something from the standard library. You'd have to write your own adapter to do that. – NathanOliver Nov 30 '20 at 20:41
  • ok, but I fear I can't do that in the midst of the competition environment as prewritten code is not allowed, anyways thanks a ton for your help. – Salman Elgamal Nov 30 '20 at 20:46
0

You could read into a temporary variable.

for (int k, i = 0; i < n; i++) cin >> k, back_inserter(A) = k;
# or nicer:
for (int i = 0; i < n; i++) {
     int k;
     cin >> k;
     back_inserter(A) = k;
}

You could provide the missing overload and read into temporary variable in it:

template<typename T>
std::istream& operator>>(std::istream& is, std::back_insert_iterator<std::vector<T>> obj) {
    T tmp;
    is >> tmp;
    obj = tmp;
    return is;
}

int main() {
    for (int i = 0; i < n; i++) cin >> back_inserter(A);
}
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • This looks pretty good and concise, thanks a lot for your help, but I really don't understand why this code works but mine doesn't, any idea? – Salman Elgamal Nov 30 '20 at 20:52
  • ? Because there is no `std::istream::operator>>(std::back_insert_operator>)`. There are only [that many std::istream::operator>>](https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt). – KamilCuk Nov 30 '20 at 22:52
  • Yeah I see, but there is one for a void* pointer right, I thought it would treat it the same as a regular pointer, can that be achieved if I cast the back_inserter somehow to a pointer? – Salman Elgamal Dec 01 '20 at 09:06
  • That makes no sense. No. The `operator>>(void*)` prints the value of the pointer. And it makes no sense to "cast an object somehow to a pointer". – KamilCuk Dec 01 '20 at 09:12