Crash on vector pop_back() of only remaining entry - c++

Code:
#include <vector>
#include <algorithm>
#include <iostream>
#include <ctime>
struct myClass {
bool bIsDead;
myClass(bool bDead) {
this->bIsDead = bDead;
}
};
void PrintVector(std::vector<myClass*> vec) {
std::cout << "The vector contains: ";
for(int i = 0; i < vec.size(); i++) {
std::cout << vec[i]->bIsDead << " ";
}
std::cout << std::endl;
}
int main() {
std::srand(std::time(0)); // use current time as seed for rng
std::vector<myClass*> myVector;
for(int i = 0; i < 10; i++) {
int tempRand = std::rand() % 2;
// int tempRand = 1;
if(tempRand == 1) {
myVector.push_back(new myClass(true));
}
else {
myVector.push_back(new myClass(false));
}
}
std::cout << "Unsorted: " << std::endl;
PrintVector(myVector);
std::sort(myVector.begin(), myVector.end(), [ ]( const myClass *lhs, const myClass *rhs )
{
return lhs->bIsDead < rhs->bIsDead;
});
std::cout << "Sorted: " << std::endl;
PrintVector(myVector);
while(myVector.back()->bIsDead) {
delete myVector.back();
myVector.pop_back();
}
std::cout << "Removed Dead Ones: " << std::endl;
PrintVector(myVector);
return 0;
}
Output for random inputs:
Unsorted:
The vector contains: 0 0 1 0 0 0 1 1 0 1
Sorted:
The vector contains: 0 0 0 0 0 0 1 1 1 1
Removed Dead Ones:
The vector contains: 0 0 0 0 0 0
Hit ENTER to continue...
Output for all 1's (i.e. pop_back removes all):
Unsorted:
The vector contains: 1 1 1 1 1 1 1 1 1 1
Sorted:
The vector contains: 1 1 1 1 1 1 1 1 1 1
Hit ENTER to continue...
For this console application I'm not given any errors or crash warnings, but it isn't outputting the two cout statements after the pop_back call for the all 1's case.
Any ideas on why popping a vector of pointers back to empty causes the program to crash?

You need to add a check for size of vector. It shouldn't be 0 if you want to access the vector's last element using back().
Change this:
while(myVector.back()->bIsDead) {
to:
while(myVector.size() > 0 && myVector.back()->bIsDead) {
Here's the correct code:
#include <vector>
#include <algorithm>
#include <iostream>
#include <ctime>
struct myClass {
bool bIsDead;
myClass(bool bDead) {
this->bIsDead = bDead;
}
};
void PrintVector(std::vector<myClass*> vec) {
std::cout << "The vector contains: ";
for(int i = 0; i < vec.size(); i++) {
std::cout << vec[i]->bIsDead << " ";
}
std::cout << std::endl;
}
int main() {
std::srand(std::time(0)); // use current time as seed for rng
std::vector<myClass*> myVector;
for(int i = 0; i < 10; i++) {
int tempRand = std::rand() % 2;
// int tempRand = 1;
if(tempRand == 1) {
myVector.push_back(new myClass(true));
}
else {
myVector.push_back(new myClass(false));
}
}
std::cout << "Unsorted: " << std::endl;
PrintVector(myVector);
std::sort(myVector.begin(), myVector.end(), [ ]( const myClass *lhs, const myClass *rhs )
{
return lhs->bIsDead < rhs->bIsDead;
});
std::cout << "Sorted: " << std::endl;
PrintVector(myVector);
while(myVector.size() > 0 && myVector.back()->bIsDead) {
delete myVector.back();
myVector.pop_back();
}
std::cout << "Removed Dead Ones: " << std::endl;
PrintVector(myVector);
return 0;
}
Quoting cppreference
Calling this function(back()) on an empty container causes undefined
behavior.
PS: You don't need to make the question look so intimidating to grab our attention.

As with most problems I have, it was something simple. Thanks to billz and juanchopanza's comments it was pointed out to me that it wasn't the pop_back() that was crashing, but rather the subsequent back() called in the while loop.
This is easily fixable in several ways, 2 examples being:
adding if(myVector.empty) {break;} into the delete's while loop
or like user3286661 said, adding a conditional to the while loop first checking if it has an element.

The problem is that you try to access myVector.back() even when the vector is already empty.
The least intrusive solution (minimal modification to your code) I can think of would this:
while (!myVector.empty() && myVector.back()->bIsDead) {
delete myVector.back();
myVector.pop_back();
}
The "right" thing to do would be to use either std::vector<myClass> or std::vector<std::unique_ptr<myClass>> (no need for manual delete) and use the erase-remove-idiom:
myVector.erase(
std::remove_if(myVector.begin(), myVector.end(),
[](const auto& p) {
return p->bIsDead; //p.bIsDead for std::vector<myClass>
}
),
myVector.end()
);
This might look more complicated, but it is safer (no accidental memory leaks), probably more efficient and makes the call to sort unnecessary.

Related

Find minimum value in vector

Below I have attached code for a project that is intended to find the lowest value in a user-inputed vector, return -1 if the vector is empty, and 0 if the vector only has one index. I have run into an issue with the condition in which a vector is empty as the unit test continues to fail the returns_negative_one_for_empty_vector test.
main.cc
#include <iostream>
#include <vector>
#include "minimum.h"
int main() {
int size;
std::cout << "How many elements? ";
std::cin >> size;
std::vector<double> numbers(size);
for (int i = 0; i < size; i++) {
double value;
std::cout << "Element " << i << ": ";
std::cin >> value;
numbers.at(i) = value;
}
double index;
index = IndexOfMinimumElement(numbers);
std::cout << "The minimum value in your vector is at index" << index << std::endl;
}
minimum.cc
#include "minimum.h"
#include <vector>
int IndexOfMinimumElement(std::vector<double> input) {
int i, min_index;
double min_ = input.at(0);
for (int i = 0; i < input.size(); i++) {
if (input.at(i) < min_) {
min_index = i;
return min_index;
}
else if (input.size() == 0) {
return -1;
}
else if(input.size() == 1) {
return 0;
}
}
};
minimum.h
#include <vector>
int IndexOfMinimumElement(std::vector<double> input);
find the lowest value in a user-inputed vector, return -1 if the
vector is empty, and 0 if the vector only has one index.
Instead of writing raw for loops, this can be accomplished much more easily by using the STL algorithm functions.
There are other issues, one being that the vector should be passed by const reference, not by value. Passing the vector by-value incurs an unnecessary copy.
#include <algorithm>
#include <vector>
#include <iostream>
int IndexOfMinimumElement(const std::vector<double>& input)
{
if (input.empty())
return -1;
auto ptrMinElement = std::min_element(input.begin(), input.end());
return std::distance(input.begin(), ptrMinElement);
}
int main()
{
std::cout << IndexOfMinimumElement({ 1.2, 3.4, 0.8, 7.8 }) << std::endl;
std::cout << IndexOfMinimumElement({}) << std::endl; // empty
std::cout << IndexOfMinimumElement({3}) << std::endl; // only 1 element
return 0;
}
Output:
2
-1
0
The relevant functions are std::min_element and std::distance. The std::min_element returns an iterator (similar to a pointer) to the minimum element in the range.
The code is written with a clear understanding of what each function does -- it is practically self-documenting. To get the minimum element, you call std::min_element. To get the distance from the first to the found minimum element, you call std::distance with an iterator to the starting position and an iterator to the ending position.
The bottom line is this: the STL algorithm functions rarely, if ever, fail when given the proper input parameters. Writing raw for loops will always have a much greater chance of failure, as you have witnessed. Thus the goal is to minimize having to write such for loops.
In IndexOfMinimumElement you return on the very first iteration, as all branches of your if/else lead to a return.
If your vector contained {14, 2, 10, 1} the index it would return would be 1, because 2 is less than 14.
Instead, you want to have a couple of conditional checks at the top of your function that return based on the length of the vector.
If the function call gets past those, it should iterate over the values in the vector, checking if they are less than the running minimum value, and update the minimum index accordingly.
int IndexOfMinimumElement(std::vector<double> input) {
if (input.size() == 0) return -1;
if (input.size() == 1) return 0;
int i = 0;
double min = input[0];
int min_idx = 0;
for (auto &v : input) {
if (v < min) {
min = v;
min_idx = i;
}
++i;
}
return min_idx;
}
A minimal test:
int main() {
std::vector<double> foo { 1.2, 3.4, 0.8, 7.8 };
std::cout << IndexOfMinimumElement(foo) << std::endl;
return 0;
}
Prints, as expected:
2

C++: confusion about accessing class data members while multithreading

I have the following minimal working example in which I create a number of markov_chain objects in a vector chains and an equal number of thread objects in a vector workers, each of which executes a markov_chain class member function sample on each of the corresponding markov_chain objects. This function takes some integer (99 in the below example) and assigns it to the acceptance public data member of the markov_chain object. I then print the value of acceptance for each object in the vector.
#include <iostream>
#include <thread>
#include <algorithm>
#include <vector>
class markov_chain
{
public:
unsigned int length{0}, acceptance{0};
markov_chain(unsigned int l) {length=l;}
~markov_chain() {}
void sample(int acc);
};
void markov_chain::sample(int acc)
{
acceptance = acc;
std::cout << length << ' ' << acceptance << std::endl;
}
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains;
std::vector<std::thread> workers;
for (int i = 0; i <= number_of_threads; i++) {
chains.push_back(markov_chain(number_of_samples));
workers.push_back(std::thread(&markov_chain::sample, chains[i], 99));
}
std::for_each(workers.begin(), workers.end(), [](std::thread &t)
{
t.join();
});
for (int i = 0; i <= number_of_threads; i++) {
std::cout << chains[i].length << ' ' << chains[i].acceptance << std::endl;
}
return 0;
}
Upon executing, the program outputs
1000 99
1000 99
1000 99
1000 99
1000 0
1000 0
1000 0
1000 0
So the program failed to change the value of acceptance for the objects in the vector chains. I don't know why this happens; the function sample successfully assigns the desired value when I use it without creating threads.
There are 2 problems with your code:
when creating each std::thread, you are passing a copy of each object as the this parameter of sample().
Pushing multiple objects into the chains vector the way you are doing may cause the vector to re-allocate its internal array, thus invaliding any object pointers you have already passed to existing threads, since those original objects are now gone after the re-allocation.
You need to fully initialize the chains vector before creating any of the threads. And you need to pass a pointer to each object to each thread.
You can reserve() the array up front to avoid re-allocation while pushing into it, eg:
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains;
std::vector<std::thread> workers;
chains.reserve(number_of_threads);
for (int i = 0; i < number_of_threads; ++i) {
chains.push_back(markov_chain(number_of_samples));
workers.push_back(std::thread(&markov_chain::sample, &chains[i], 99));
}
for(auto &t : workers) {
t.join();
}
for (auto &c : chains) {
std::cout << c.length << ' ' << c.acceptance << std::endl;
}
return 0;
}
Demo
However, since all of the objects are being initialized with the same starting value, an easier way is to simply get rid of chains.push_back() altogether and use chains.resize() instead, eg:
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains;
std::vector<std::thread> workers;
chains.resize(number_of_threads, markov_chain(number_of_samples));
for (int i = 0; i < number_of_threads; ++i) {
workers.push_back(std::thread(&markov_chain::sample, &chains[i], 99));
}
for(auto &t : workers) {
t.join();
}
for (auto &c : chains) {
std::cout << c.length << ' ' << c.acceptance << std::endl;
}
return 0;
}
Demo
Or, even use the vector constructor itself:
int main()
{
int number_of_threads{3};
int number_of_samples{1000};
std::vector<markov_chain> chains(number_of_threads, markov_chain(number_of_samples));
std::vector<std::thread> workers;
for (int i = 0; i < number_of_threads; ++i) {
workers.push_back(std::thread(&markov_chain::sample, &chains[i], 99));
}
for(auto &t : workers) {
t.join();
}
for (auto &c : chains) {
std::cout << c.length << ' ' << c.acceptance << std::endl;
}
return 0;
}
Demo

what's wrong with vector::reserve? [duplicate]

This question already has answers here:
Choice between vector::resize() and vector::reserve()
(4 answers)
Why can't you access memory allocated by vector::reserve
(3 answers)
Closed 3 years ago.
I am just trying to learn STL for Competitive programming and stuck with this doubt!
1. When i use vector::reserve(n) my loops labeled as loop1 and loop2 don't print anything.
2. but when i use vector::assign(n,0) my loops labeled as loop 1 and loop 2 works fine.
why is it so?
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
int test;
scanf("%d", &test);
while (test > 0) {
int n;
scanf("%d", &n);
vector<int> arr;
arr.reserve(n);
//arr.assign(n,0);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
sort(arr.begin(), arr.end());
vector<int>::iterator itr;
// loop1
for (int x : arr) {
printf("%d ", x);
}
//loop2
for (itr = arr.begin(); itr != arr.end(); itr++) {
printf("%d ", *itr);
}
test--;
}
return 0;
}
This is a common mistake. std::vector::reserve does not create elements or change the size of the container; you're actually causing undefined behavior. reserve changes just the capacity. You are looking for std::vector::resize to change the size. Here's an example for clarity:
#include <iostream>
#include <vector>
int main() {
std::vector<int> ivec;
std::cout << ivec.size() << " - " << ivec.capacity() << '\n'; // 0 - 0
ivec.reserve(100);
std::cout << ivec.size() << " - " << ivec.capacity() << '\n'; // 0 - 100
ivec.resize(30);
std::cout << ivec.size() << " - " << ivec.capacity() << '\n'; // 30 - 100
}
vector::reserve doesn't change the size of the vector. Instead, it just allocates additional memory, increasing the capacity of the vector for operations such as push_back.
For example:
std::vector<int> v;
// v.size() == 0, v.capacity() == 0
for(int i = 0; i < 100; i++) {
v.push_back(i); // This will resize the vector a few times
}
// v.size() == 100, v.capacity() >= 100
Versus
std::vector<int> v;
v.reserve(100);
// v.size() == 0, BUT v.capacity() >= 100
for(int i = 0; i < 100; i++) {
v.push_back(i); // This won't resize the vector now
}
If you want to change the size of the vector, use vector::resize.

How To Shift Array Elements to right and replace the shifted index with string in Visual C++

VISUAL C++ Question
Hi,
I have array of 3 elements and I want to shift its elements to the right and replace the shifted index cell with "SHIFTED" string and this should loop until all the cells has "SHIFTED" string.
For example:
int a[x]={0,1,2};
Initial index and elements Order:
[0]=0
[1]=1
[2]=2
should become in the:
1st loop:
[0]=SHIFTED
[1]=0
[2]=1
2nd Loop:
[0]=SHIFTED
[1]=SHIFTED
[2]=0
3rd Loop:
[0]=SHIFTED
[1]=SHIFTED
[2]=SHIFTED
I know I can do that with memmove() but I don't want to use any function in it.
Would you please help me; here is my work:
#include <iostream>
#include <string>
#include <stdio.h>
#include <cstdlib>
using namespace std;
int const ARRAY_SIZE=3;
int main()
{
int Array[ARRAY_SIZE];
int iniPostion,newPostion;
string x="SHIFTED";
for(iniPostion=0; iniPostion<ARRAY_SIZE; iniPostion++)
{
Array[iniPostion] = iniPostion;
cout << "Cell [" << iniPostion << "] Initial Element is: (" << Array[iniPostion] << ")" << endl;
}
cout << endl;
for(newPostion=0; newPostion<ARRAY_SIZE; newPostion++)
{
Array[newPostion]=newPostion;
cout << "Cell [" << newPostion << "] New Element is: (";
if(Array[newPostion-1]<0)
{
cout << x << ")\n";
}
else
{
cout << Array[newPostion-1] << ")" << endl;
}
}
return 0;
}
As Peter mentioned in his answer, you cannot assign a string to a int. I've assumed SHIFTED to be -1. So every time you shift you bring in a -1 in the gap created.
You need two loops. The outer loops iterates N (3) times and inner loop starts at the end of the array and copies (n-1)th element to nth position:
for(int count = 0;count < N;count++){
for(newPostion=ARRAY_SIZE-1; newPostion > count;newPostion--)
Array[newPostion]=Array[newPostion - 1]; // copy
Array[newPostion]= -1; // fill the gap.
// print.
for(iniPostion=0; iniPostion<ARRAY_SIZE; iniPostion++) {
cout << "Cell [" << iniPostion << "] Initial Element is: (" << Array[iniPostion] << ")" << endl;
}
cout<<endl;
}
Sample run:
# g++ a.cpp && ./a.out
Cell [0] Initial Element is: (0)
Cell [1] Initial Element is: (1)
Cell [2] Initial Element is: (2)
Cell [0] Initial Element is: (-1)
Cell [1] Initial Element is: (0)
Cell [2] Initial Element is: (1)
Cell [0] Initial Element is: (-1)
Cell [1] Initial Element is: (-1)
Cell [2] Initial Element is: (0)
Cell [0] Initial Element is: (-1)
Cell [1] Initial Element is: (-1)
Cell [2] Initial Element is: (-1)
It is a bit unclear, how you can expect to have string ("SHIFTED") in an array of integers.
However, for this operation you can use the rotate algorithm:
#include <iostream>
#include <algorithm>
#include <string>
int const ARRAY_SIZE=3;
void print(std::string* array) {
for (int i = 0; i != ARRAY_SIZE; ++i) {
std::cout << array[i] << ' ';
}
std::cout << '\n';
}
int main()
{
std::string Array[ARRAY_SIZE] = {"0", "1", "2"};
print(Array);
//the last item ends up at the beginning of the array
std::rotate(Array, Array + ARRAY_SIZE - 1, Array + ARRAY_SIZE);
//now overwrite the item that used to be last
Array[0] = "SHIFTED";
print(Array);
return 0;
}
It would probably be simpler and more efficient with a suitable container, such as std::deque or std::list where you could pop_back the last value and push_front the new value.
I have array of 3 elements and I want to shift its elements to the right and replace the shifted index cell with "SHIFTED" string and this should loop until all the cells has "SHIFTED" string.
This doesn't make sense at all. You have an array of numbers (integers), which of course can't contain a string. What you can do is e.g. inserting 0 or -1 to denote the shifted element.
The shifting itself can be easily implemented through a std::rotate operation.
But since all elements contain the same thing in the end, why don't you just assign them directly without all the shifting?
Here is my simple solution in plain old C
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char **argv) {
int MAX_LEN = 11;
int numOfShifts = 1;
if ( argc > 1 ) {
numOfShifts = atoi(argv[1]);
}
printf("Number of shifts = %d\n",numOfShifts);
int arr[] = { 0,1,2,3,4,5,6,7,8,9,10 };
int i;
int n; // number of shifts index
for ( n = 0; n < numOfShifts; n++ ) {
for ( i = MAX_LEN - 1; i >= 0; i-- ) {
if ( i == 0 ) {
arr[i] = -1;
} else {
arr[i] = arr[i-1];
}
}
}
// output
for( i = 0; i < MAX_LEN; i++ ) {
printf("Arr[%d] = %d\n", i, arr[i]);
}
}
This reeks of homework...
Is there a reason you can't just keep track of how many shifts you've done and just take that into account when you print?
#include <iostream>
int const ARRAY_SIZE=3;
class Shifter
{
public:
Shifter(const int* array_, size_t size_)
: array(array_), size(size_), shifts(0) {}
void Shift(size_t steps = 1) { shifts += steps; if(shifts > size) shifts = size; }
void Print(std::ostream& os) const;
private:
const int* array;
size_t size;
size_t shifts;
};
void Shifter::Print(std::ostream& os) const
{
for(size_t i = 0; i < size; ++i)
{
os << "Cell [" << i << "] = ";
if(i < shifts)
os << "SHIFTED";
else
os << array[i - shifts];
os << std::endl;
}
}
std::ostream& operator <<(std::ostream& os, const Shifter& sh)
{
sh.Print(os);
return os;
}
int main(void)
{
// Initialize the array.
int a[ARRAY_SIZE];
for(size_t iniPostion=0; iniPostion < ARRAY_SIZE; iniPostion++)
a[iniPostion] = iniPostion;
Shifter sh(a, ARRAY_SIZE);
std::cout << "Initial contents:" << std::endl;
std::cout << sh << std::endl;
// Do the shifts.
for(size_t newPostion = 0; newPostion < ARRAY_SIZE; newPostion++)
{
std::cout << "Shift by 1..." << std::endl;
sh.Shift();
std::cout << sh << std::endl;
}
return 0;
}
You can simple move memory.
// shift down
int a[ 10 ];
memmove( a, a +1, sizeof( a ) -sizeof( a[ 0 ] ) );

Counting occurrences in a vector

This program reads strings of numbers from a txt file, converts them to integers, stores them in a vector, and then tries to output them in an organized fashion like so....
If txt file says:
7 5 5 7 3 117 5
The program outputs:
3
5 3
7 2
117
so if the number occurs more than once it outputs how many times that happens. Here is the code so far.
#include "std_lib_facilities.h"
int str_to_int(string& s)
{
stringstream ss(s);
int num;
ss >> num;
return num;
}
int main()
{
cout << "Enter file name.\n";
string file;
cin >> file;
ifstream f(file.c_str(), ios::in);
string num;
vector<int> numbers;
while(f>>num)
{
int number = str_to_int(num);
numbers.push_back(number);
}
sort(numbers.begin(), numbers.end());
for(int i = 0; i < numbers.size(); ++i)
{
if(i = 0 && numbers[i]!= numbers[i+1]) cout << numbers[i] << endl;
if(i!=0 && numbers[i]!= numbers[i-1])
{
cout << numbers[i] << '\t' << counter << endl;
counter = 0;
}
else ++counter;
}
}
Edit: Program is getting stuck. Looking for an infinite loop right now.
You could use a map of numbers to counters:
typedef map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
CounterMap::iterator it(counts.find(numbers[i]));
if (it != counts.end()){
it->second++;
} else {
counts[numbers[i]] = 1;
}
}
... then iterate over the map to print results.
EDIT:
As suggested by lazypython: if you have the TR1 extensions [wikipedia.org] available, unordered_map should have better performance...
typedef std::tr1::unordered_map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
CounterMap::iterator it(counts.find(numbers[i]));
if (it != counts.end()){
it->second++;
} else {
counts[numbers[i]] = 1;
}
}
How about using a map, where the key is the number you're tracking and the value is the number of occurrences?
If you must use a vector, you've already got it sorted. So just keep track of the number you previously saw. If it is the same as the current number, increment the counter. Every time the number changes: print out the current number and the count, reset the count, set the last_seen number to the new number.
Using a map is the practical solution. What you should do is to solve this problem :)
This is called frequency counter. So, you have a sorted vector and all what you have to do is to count successive equal numbers. In other words, you have to check each number with its successor.
for(size_t i = 0; i < numbers.size(); i++)
{
size_t count = 1;
size_t limit = numbers.size() - 1;
while(i < limit && numbers[i] == numbers[i+1])
{
count++;
i++;
}
std::cout << numbers[i] << "\t" << count << std::endl;
}
This program reads strings of numbers
from a txt file, converts them to
integers, stores them in a vector, and
then tries to output them in an
organized fashion like so....(emphasis added)
What is the point of this storage step? If you are reading the numbers from a file, then you already have them in order, ready to be processed (counted) one at time, as you encounter them.
However, I would need a way for it to know when it sees a new number.
I advise you to have a look at std::set or std::map. I expect either of these containers would do what you're looking for.
Std::count() fits the bill nicely.
std::vector<int>::const_iterator cur = numbers.begin();
std::vector<int>::const_iterator last = numbers.end();
while (cur != last) {
unsigned cnt = std::count(cur, last, *cur);
std::cout << *cur;
if (cnt != 1) {
std::cout << " " << c;
}
std::cout << std::endl;
int saved = *cur;
while (*cur == saved) {
++cur;
}
}
Of course there are a bunch of other algorithms out there that will do the same job. Play with things like std::equal_range() in conjunction with std::distance() will do the job just as nicely.
That was fun:
#include <map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
struct IncrementMap
{
IncrementMap(std::map<int,int>& m): m_map(m) {}
void operator()(int val) const
{
++m_map[val];
}
std::map<int,int>& m_map;
};
struct SpecialPrint
{
SpecialPrint(std::ostream& s): m_str(s) {}
void operator()(std::map<int,int>::value_type const& value) const
{
m_str << value.first;
if (value.second != 1)
{
m_str << "\t" << value.second;
}
m_str << "\n";
}
std::ostream& m_str;
};
int main()
{
std::fstream x("Plop");
std::map<int,int> data;
std::for_each( std::istream_iterator<int>(x),
std::istream_iterator<int>(),
IncrementMap(data)
);
std::for_each( data.begin(),
data.end(),
SpecialPrint(std::cout)
);
}