I can't understand the use of std::istream_iterator - c++

I can't understand the code below.
(from https://www.boost.org/doc/libs/1_74_0/more/getting_started/unix-variants.html)
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
using namespace boost::lambda;
typedef std::istream_iterator<int> in;
std::for_each(
in(std::cin), in(), std::cout << (_1 * 3) << " " );
}
The web page doesn't explain anything for the code.
What I can't understand is the line with std::for_each function.
std::for_each is defined as below.
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn);
So first is in(std::cin), last is just in(), the function is the cout statement.
Could anyone explain to me the syntax of first and last syntax and meaning in the example code?
The first iterator seems to be constructed with initial value std::cin, but what's the use of in() for the last value?
I also can't understand the _1 part.
The program outputs 3 * any number of integer values I type in.

First a little explanation about the std::for_each function.
The function loops over a set of iterators, from the beginning to the end, calling a function for each element in the range.
If you have e.g. a vector of integers:
std::vector<int> v = { 1, 2, 3, 4 };
and want to print print them, then you could do:
std::for_each(v.begin(), v.end(), [](int val) { std::cout << val; });
The above call to std::for_each is equivalent to:
for (auto i = v.begin(); i != v.end(); ++i)
{
std::cout << *i;
}
Now if we go the usage of the std::istream_iterator in the question, it is wrapping the input operator >> using iterators.
Rewriting the std::for_each call using standard C++ lambdas, it would look like this:
std::for_each(in(std::cin), in(), [](int value) { std::cout << (value * 3) << " " ); });
If we translate it to the "normal" for iterator loop then it becomes:
for (auto i = in(std::cin); i != in(); ++i)
{
std::cout << (*i * 3) << " ";
}
What it does, is reading integer input (until end-of-file or an error) from std::cin, and then output the value multiplied by 3 and a space.
If you're wondering about in(std::cin) and in(), you have to remember that in is an alias for the type std::istream_iterator<int>.
That means in(std::cin) is the same as std::istream_iterator<int>(std::cin). I.e. it creates a std::istream_iterator<int> object, and passes std::cin to the constructor. And in() constructs an end-iterator object.
Making it even clearer, the code is equivalent to:
std::istream_iterator<int> the_beginning(std::cin);
std::istream_iterator<int> the_end; // Default construct, becomes the "end" iterator
for (std::istream_iterator<int> i = the_beginning; i != the_end; ++i)
{
int value = *i; // Dereference iterator to get its value
// (effectively the same as std::cin >> value)
std::cout << (value * 3) << " ";
}

Could anyone explain to me the syntax of first and last syntax and meaning in the example code?
The first iterator seems to be constructed with initial value std::cin, but what's the use of in() for the last value?
If you look at the description of the constructor of std::istream_iterator you can see that in() constructs the end-of-stream iterator.
istream_iterator(); // < C++11
constexpr istream_iterator(); // > C++11
Constructs the end-of-stream iterator, value-initializes the stored value. This constructor is constexpr if the initializer in the definition auto x = T(); is a constant initializer (since C++11).
As for in(std::cin):
istream_iterator( istream_type& stream );
istream_iterator( const istream_iterator& other ); //< C++11
istream_iterator( const istream_iterator& other ) = default; // > C++11
Initializes the iterator, stores the address of stream in a data member, and performs the first read from the input stream to initialize the cached value data member.
source
And I also can't understand the _1 part.
What this does is to replace the placeholder _1 with every element in the iteration sequence and multiply it by 3, using the result in the output stream, as it should, given the unary function argument.
for_each(a.begin(), a.end(), std::cout << _1 << ' ');
The expression std::cout << _1 << ' ' defines a unary function object. The variable _1 is the parameter of this function, a placeholder for the actual argument. Within each iteration of for_each, the function is called with an element of a as the actual argument. This actual argument is substituted for the placeholder, and the “body” of the function is evaluated.
source

Related

std::remove() works as expected with literal but not with dereferenced iterator

While learning remove-erase idiom, as well as understanding how std::min_element() work How to use std::min_element in C++17?. I thought to try removing minimum element from the following piece of code:
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v{3, 1, 4, 1, 5, 9};
std::vector<int>::iterator result = std::min_element(v.begin(), v.end());
std::cout << "min element at: " << std::distance(v.begin(), result);
}
There are two minimum elements in v. I tried to remove both of them with added diagnostics
int main()
{
std::vector<int> v{3, 1, 4, 1, 5, 9};
std::vector<int>::iterator result = std::min_element(v.begin(), v.end());
v.erase(result); // This removes just one minimum. What if need to remove all?
v.push_back(1); // Okay, let's add the minimum again
std::vector<int>::iterator another_result = std::min_element(v.begin(), v.end());
std::cout << "min element: " << *another_result << std::endl;
auto iter = std::remove(std::begin(v), std::end(v), *another_result);
// If I write 1 instead of *another_result, I manage to remove all 1's. No need to use iter-1 in erase idiom then.
std::cout << "\nWhere is my iterator pointing? It is at: " << std::distance(v.begin(), iter);
v.erase(iter, std::end(v)); // All the minimum are gone if I use iter-1 instead of iter and use *another_result
std::for_each(v.begin(), v.end(), [](const int& x){std::cout << x << " ";}); // Why is still "1" there?
}
link
My questions are, as highlighted in the code with the comments,
Why I am able to remove all the instances of minimum by providing a literal but not a de-referenced iterator? i.e.
Why does the following work?
auto iter = std::remove(std::begin(v), std::end(v), 1);
However,
If I choose to stick with a de-reference iterator,
auto iter = std::remove(std::begin(v), std::end(v), *another_result);
Doesn't remove all the instances of minimum while sticking to remove-erase idiom.
It looks like you are comparing with a reference into the vector. The element you passed in then gets moved by remove and when comparing against it a second time the reference observes some other value.
This works just fine:
int by_value = *another_result;
auto iter = std::remove(std::begin(v), std::end(v), by_value);
The third parameter of the std::remove overload you're using takes a const T&, but it's "invalidating" the reference in the process of doing its operation.
If you look at the "possible implementation" on en.cppreference
template< class ForwardIt, class T >
ForwardIt remove(ForwardIt first, ForwardIt last, const T& value)
{
first = std::find(first, last, value);
if (first != last)
for(ForwardIt i = first; ++i != last; )
if (!(*i == value))
*first++ = std::move(*i); //here it changes the value that "value" points to
//if you are using a reference of an element inside the vector
return first;
}
This problem is also mentioned in the "Notes" section as:
Because std::remove takes value by reference, it can have unexpected
behavior if it is a reference to an element of the range [first,
last).
If you want to remove all the minimum values in one go, you could do something a little more odd like this:
template<class T>
void remove_min( std::vector<T> &container ) {
if ( container.empty() ) return;
T min_val = *std::min_element( container.begin(), container.end() );
container.erase( std::remove( container.begin(), container.end(), min_val ), container.end() );
}
Note that the min_val is a copy first (see PeterT's answer for explanation). The above can probably be modified to work with other containers.
Keep in mind that std::remove doesn't really remove anything. The return value from the function will point to after where the new last element would be, then call the container's erase method from there to remove all the elements from that point on.

Iterate backwards using iterators

For simplification of my question i will use std::string::iterator and std::string::reverse_iterator but the question is about iterators in general.
Is there any particular reason to iterate backwards using the following loop:
std::string s = "something";
for (std::string::reverse_iterator it = s.rbegin(); it != s.rend(); ++it)
rather than this one:
std::string s = "something";
std::string::iterator it = in.end();
while(it!=in.begin())
{
it--;
//do something
}
Reverse iterators allow you to reuse generic code because you can treat them like normal iterators, calling ++ to go backwards. For example:
#include <iostream>
#include <string>
template <class Iterator>
void printAll(Iterator begin, Iterator end)
{
for (auto it = begin; it != end; ++it) // ++ can mean "go backwards"
// if Iterator is a reverse
// iterator
{
std::cout << *it << "\n";
}
}
int main()
{
std::string s = "123";
printAll(s.begin(), s.end()); // prints 1, 2, 3
printAll(s.rbegin(), s.rend()); // prints 3, 2, 1
}
Notice how you do not need to write a reverse version for printAll using --.
Now, consider all the functions in <algorithm>. The existence of reverse iterators means that you can easily use all of them in a reverse manner. For example, there is std::copy_n, but not std::reverse_copy_n, but with reverse iterators, it's not necessary, because you can write something like this:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
int main()
{
std::string input = "abcdef";
std::string output;
std::string output_reversed;
// copy the first 3 elements:
std::copy_n(input.begin(), 3, std::back_inserter(output));
// copy the first 3 elements going backwards, starting at the last one:
std::copy_n(input.rbegin(), 3, std::back_inserter(output_reversed));
std::cout << output << "\n"; // prints abc
std::cout << output_reversed << "\n"; // prints fed
}
For non-generic code, such as in your question, it's more of a style issue, with few technically sound arguments to prefer one over the other.
Since begin() points to the first member, and end() points to the member next to the last, that is all about clean code (since in case of using not reverse iterators you would do iterator decrement first, then the code you want to execute, then you will compare iterator with begin(), but it is wrong, since begin() points to an existing first element.
std::vector::end() at cplusplus.com

How to get max_element from vector<std::string>

Using the code from cplusplus.com, I am trying to find the max int value in an vector<std::string>.
the vector is in std::string format and there is no choice here.
bool myfn(int i, int j)
{
return i < j;
}
vector<std::string> dat;
dat.push_back(2.1);
dat.push_back(5.3);
for (int l = 0; l < dat.size(); ++l)
{
std::cout << *std::max_element(dat.begin(), dat.end(), myfn) << '\n';
}
expected output:
3
error:
.cpp:76:93: error: no matching function for call to 'max_element(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >::size_type, bool (&)(int, int))'
How do you find the max value in a vector<std::string>?
You're calling max_element with the wrong arguments. It takes two iterators and a function:
template <class ForwardIterator, class Compare>
ForwardIterator max_element (ForwardIterator first, ForwardIterator last,
Compare comp);
You're calling it with a vector and a size. The confusion might stem from the example on the reference you link where they do:
std::min_element(myints, myints +7, myfn)
// ^^^^^^ ^^^^^^^^^
// int* int*
In this case, both myints and myints + 7 are of type int*, and a raw pointer is an iterator. In your case however, you are passing two different types (vector<string> and size_t), neither of which is an iterator. So you need to instead do:
*std::max_element(dat.begin(), dat.end(), myfn)
Or, to illustrate something equivalent to the example in the reference (although definitely prefer the above):
std::string* first = &dat[0];
*std::max_element(first, first + dat.size(), myfn)
Which works because in this case I am passing two string*'s, which are iterators.
(Also based on your usage, dat should be vector<int> not vector<string>.)
You have a vector that is full of strings vector<std::string> dat; but yet your comparison functions takes 2 integers. You might want to either change the type that is stored in the vector or change the comparison function you use. If you use integers then the default comparison operator will do what you want already without you needing to write a custom function.
Also std::max_element expects to get iterators one for the start and one for the end, so you need to change your call to be something like std::max_element(dat.begin(), dat.end(), myfn). You might notice that the loop you have is actually not needed because you already go over that range with the call to std::max_element all this loop does is compute the exact same value multiple times, you only need to compute it once.
Your std::vector dat declaration is wrong as you want to push_back int.
std::max_element and std::min_element returns an iterator not value. You can have a look into the following example
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<int> v {1,2,3,4,6};
auto biggest = std::max_element(std::begin(v), std::end(v));
std::cout << "Max element is " << *biggest
<< " at position " << std::distance(std::begin(v), biggest) << std::endl;
auto smallest = std::min_element(std::begin(v), std::end(v));
std::cout << "min element is " << *smallest
<< " at position " << std::distance(std::begin(v), smallest) << std::endl;
return 0;
}
Pointers can be iterators. This is what allows you to use arrays as a range in standard library functions. myints is an expression that refers to the first element of the array, and myints + 7 refers to one past the end of the array. Equivalently you can do std::begin(myints) and std::end(myints). Standard containers expose iterators in the form of these member functions myvector.begin() and myvector.end(). You pass these iterators, not the container and size, to std::max_element.
By default, std::max_element uses operator< to compare the elements. You don't need a comparator functor in this instance.
Your std::vector's value_type is std::string, but you're trying to pass an int. Either change the value_type to int, or use a string conversion function, i.e. C++11's std::to_string.
Finally, your loop is completely unnecessary. std::max_element operators over a range.
std::vector<int> dat;
dat.push_back(1);
dat.push_back(3);
std::cout << *std::max_element(dat.begin(), dat.end()) << '\n';

Making a vector element into a string for comparison?

I'm kind of confused with vectors in C++; this is my first time using them. I made a vector of strings, and I am trying to compare elements in that vector against a letter.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
/* Head ends here */
void displayPathtoPrincess(int n, vector <string> grid){
for(vector<string>::iterator it = grid.begin(); it != grid.end(); ++it) {
if(*it.strcompare('p') != 0)
cout << 'Princess found!';
}
}
/* Tail starts here */
int main() {
int m;
vector <string> grid;
cin >> m;
for(int i=0; i<m; i++) {
string s; cin >> s;
grid.push_back(s);
}
displayPathtoPrincess(m,grid);
return 0;
}
Why won't this work? Won't *it always be a string type?
Here is my error:
error: 'std::vector >::iterator' has no member named 'strcompare'
First, in this context, . binds tighter than *, so this
*it.strcompare('p')
is equivalent to
*(it.strcompare('p'))
so you should call something like
it->methodName(args)
Second, you need to call a method of std::string, presumably std::string::compare.
Note that if all you want to do is search for an entry equal to "p", then all you have to do is
auto it = std::find(grid.begin(), grid.end(), "p");
if (it != v.end()) std::cout << "Princess found!" << std::endl;
The class std::string is basic_string ( http://en.cppreference.com/w/cpp/string/basic_string ) and I do not think this class has a standard strcompare member function(Though some compilers do provide one).
I think you are trying to do something like:
if(*it == String("P"))
Which can more simply be written as:
if(*it == "P")
for an example: http://ideone.com/isa9Il
There is no strcompare in the Standard Library.
Perhaps you meant compare?
Also, yes *it will be a string -- but 'p' is not. That is a char. You need to either convert 'p' to a string (eg string s(1,'p')) or compare the first (or last) character in *it to 'p' (eg (*it)[0] == 'p' -- warning, unsafe as is)
Finally, others have already mentioned this, but *it.strcompare would not bind as (*it).strcompare, but rather as *(it.strcompare). Meaning, you are trying to call a method called strcompare on the iterator, rather than what the iterator refers to. Even if string had a method called strcompare (which it doesn't), your code still wouldn't compile.

How to check if the iterator is initialized?

If I use a default constructor for an iterator, how to check if it was assigned later on?
For pointers, I could do this :
int *p = NULL;
/// some code
if ( NULL == p ) {
// do stuff
}
How do I do the above for iterators?
Is it possible at all?
#include <iostream>
#include <list>
int main ()
{
std::list<int>::iterator it;
if ( NULL == it ) // this fails
{
std::cout<<"do stuff" << std::endl;
}
}
I managed to find this in the current standard (c++03 ). 24.1 p 5 tells :
Just as a regular pointer to an array guarantees that there is a
pointer value pointing past the last element of the array, so for any
iterator type there is an iterator value that points past the last
element of a corresponding container. These values are called
past-the-end values. Values of an iterator i for which the expression
*i is defined are called dereferenceable. The library never assumes
that past-the-end values are dereferenceable. Iterators can also have
singular values that are not associated with any container. [Example:
After the declaration of an uninitialized pointer x (as with int* x;),
x must always be assumed to have a singular value of a pointer. ]
Results of most expressions are undefined for singular values; the
only exception is an assignment of a non-singular value to an iterator
that holds a singular value. In this case the singular value is
overwritten the same way as any other value. Dereferenceable values
are always non- singular.
(Emphasis mine)
So the answer is : no, it is not possible.
Most iterators don't have any global special values in the same way that all pointers can be NULL. Typically, though, you'll be working with specific containers, and if you keep one iterator per container, then you can use end() as the sentinel value:
std::list<int> mylist;
std::list<int>::iterator it = mylist.end();
/* do stuff */
if (it == mylist.end()) { ... }
I'm not sure if insertion/deletion invalidates the end() iterator, though, so if you're planning on modifying your container, maybe save a copy of the original end, too:
std::list<int>::iterator end = mylist.end(), it = end;
if (it == end) { ... }
Though again I'm actually not sure if it's well-defined to compare two invalid iterators (in the event that the two do get invalidated).
This question has already been treated in Stackoverflow. The quintessence is that the default constructor initializes an iterator to a singular value, and the only addmissible operation on it is to assign it another iterator value. In particular it is not possible to query the value of such unitialized iterator. Therefore it is a good programming practice to initialize the iterator to a specific value of a specific container, which then can be tested for.
Since there is no default value for iterators (like there is NULL for pointers), in situation where i need a common default value for a Object::iterator (before any actual Object has been created) I create a dummy static variable and use its ::end() as the default.
Update : This only works for Release, because in DEBUG (or with _HAS_ITERATOR_DEBUGGING=1) comparison operators check if both iterators point to the same object/container.
For example for vector<int> I would do :
class A
{
public :
A() : myIterator1(dummyVector.end()), myIterator2(dummyVector.end()) {}
// needed iterators
vector<int>::iterator myIterator1;
vector<int>::iterator myIterator2;
static const vector<int> dummyVector;
}
#define IT_NULL A::dummyObject.end()
void maint() {
A::dummyObject = vector<int>(); // initialize the Null iterator
A a;
if(a.myIterator1 == IT_NULL) cout << "Iterator not yet initialized";
}
You can't. ll you can do is compare against list end
it != mylist.end();
In C++, uninitialized local variables can have any value i.e it contains simply garbage. That implies, you cannot check it against some well-defined value, to determine if the variable is uninitialized or not.
Not only that if the variable is not initialized and you write this:
if ( NULL == it ) // this fails
then it invokes undefined behavior.
Maybe you should always assign a predefined value, like NULL, after creating the iterator. Later you can easily check against NULL.
This will make your code more portable, as you will not depend on what starting values the uninitialized variables take at the beginning.
if(std::list<int>::iterator() == it)
But I suspect... may it's possible, that a valid iterator could pass the comparison.
Better to avoid these situations. If it's impossible store the iterator by a pointer.
std::auto_ptr<std::list<int>::iterator> it;
The best way to do this I can think of is something like
#include <utility>
#include <map>
#include <typeinfo>
#include <string>
namespace nulliterators {
typedef std::map<std::string, void*> nullcntT;
nullcntT nullcontainers;
template<class containerT>
typename containerT::iterator iterator() {
containerT* newcnt = new containerT();
std::string cnttypename = typeid(*newcnt).name();
nullcntT::iterator i = nullcontainers.find(cnttypename);
if (i==nullcontainers.end()) {
nullcontainers.insert(make_pair(cnttypename, newcnt));
return newcnt->end();
}else{
delete newcnt;
return (static_cast<containerT*>(i->second))->end();
}
}
}
template<class containerT>
typename containerT::iterator nulliterator() { return nulliterators::iterator<containerT>(); }
#include <list>
#include <iostream>
int main(){
std::list<int>::iterator nullinitized = nulliterator< std::list<int> >();
std::list<int> somelist;
std::list<int>::iterator initialized = somelist.end();
if (nullinitized == nulliterator< std::list<int> >())
std::cout << "nullinitized == nulliterator< std::list<int> >()\n"; //true
else
std::cout << "nullinitized != nulliterator< std::list<int> >()\n";
if (initialized == nulliterator< std::list<int> >())
std::cout << "initialized == nulliterator< std::list<int> >()\n";
else
std::cout << "initialized != nulliterator< std::list<int> >()\n"; //true
return 0;
}
but it's not exactly a safe solution (because it relies on the non-const global containers in nullcontainers).
As far as I know you must always initialize your iterators and the easiest way is to make them equal to 'container'.end()
In certain cases it looks like working, we had some problems with code that worked with VC6 and stopped working with VC2010. Look at this example compiled with g++ where it works for the vector but not for the map:
# Test iterator init, compile with: g++ test-iterator.cpp -o test-iterator
#include <iostream>
#include <vector>
#include <map>
int main()
{
std::vector<int> vec;
std::vector<int>::iterator it;
if (it != vec.end())
{
std::cout << "vector inside!" << std::endl;
}
else
{
std::cout << "vector outside!" << std::endl;
}
std::map<int, int> mp;
std::map<int, int>::iterator itMap;
if (itMap != mp.end())
{
std::cout << "map inside!" << std::endl;
}
else
{
std::cout << "map outside!" << std::endl;
}
return 0;
}
I used the following solution:
const MyList_t::const_iterator NullIterator(NULL);
const_iterator MyList_t::MyIterator;
Then a check is possible:
if (NullIterator != MyIterator) {}