Reputation: 1633
I'm trying to copy some ints
from stdin
into a vector
. I have the code working but I'm unsure why I need the ()
after the second argument of copy
. By this I mean the istream_iterator<int>()
argument in the copy
call.
Code here...
#include <iterator>
#include <vector>
#include <iostream>
using std::vector;
using std::copy;
using std::cin;
using std::istream_iterator;
int main()
{
vector<int> nums;
copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(nums)); // why do I need the empty brackets after the 2nd argument?
return 0;
}
If I remove the brackets I get an error from the compiler, however if I slightly modify my code to code below my program works fine.
int main()
{
vector<int> nums;
istream_iterator<int> end; // no brackets used here
copy(istream_iterator<int>(cin), end, back_inserter(nums));
return 0;
}
I'm coming from a Java background so empty brackets simply means you have used an empty constructor. The first code snippet goes against what I thought I understood, from my understanding in C++ if you want to use an empty constructor you simply miss off the ()
however this isn't the case here
help!
Upvotes: 2
Views: 175
Reputation: 180595
The line
copy(istream_iterator<int>(cin), istream_iterator<int>, back_inserter(nums));
is meaningless. istream_iterator<int>
is a type not an object. You need to use ()
to create an unnamed, temporary, default-constructed object of the type istream_iterator<int>
.
Using
istream_iterator<int> end;
You declare an object of the type istream_iterator<int>
, and you do not need the parentheses, as it is default-constructed without them. In fact, if you had used parentheses, like:
istream_iterator<int> end();
Then you would have run into a most vexing parse issue and end
would now be a function taking nothing and returning a istream_iterator<int>
.
Upvotes: 3
Reputation: 172924
It might be confusing but both cases creating an object by default constructor. And for the 1st case you must use ()
, for the 2nd case you must not use ()
.
istream_iterator<int>()
creates a temporary object by default constructor. Without ()
, istream_iterator<int>
is just a type name, which doesn't make sense because an instance of the type expected.
istream_iterator<int> end;
creates a named object by default constructor too. You can't use ()
here, otherwise it will become a declaration of function, which takes no parameter and returns istream_iterator<int>
. See Most vexing parse.
Upvotes: 1
Reputation: 726579
I have the code working but I'm unsure why I need the
()
after the second argument of copy
You need them to construct an iterator in place, instead of declaring a separate variable representing one-past-the-end of an input stream. If you write
istream_iterator<int>
without parentheses, that would be a type name. With parentheses that's an invocation of a default constructor:
istream_iterator<int>()
An istream_iterator<int>
object is constructed in place, and passed to std::copy
as its second argument. By convention, the default constructor of istream_iterator<T>
gives you an instance of the iterator that signals one-past-the-end of a stream.
Upvotes: 1