Examples of lambda functions, std::for_each / max_element / remove_if etc

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite












I have written a cpp program which demonstrates the use of the following functionalities in modern cpp.



Lambda Functions
std::generate
std::vector
std::erase
std::remove_if
std::remove
std::max_element
std::for_each
std::shuffle



I want to understand the following



(1) Have I written the code properly or there are somethings which needs to be improved.



(2) Will it be helpful if I write it as a blog for others. If yes, do I need to add more comments etc to make it more consumable?



 /*
* Copyright Rishi Agrawal <rishi.b.agrawal@gmail.com>
*
* The idea behind this program is to understand how to use the following.
* Lambda Functions
* std::generate
* std::vector
* std::erase
* std::remove_if
* std::remove
* std::max_element
* std::for_each
* std::shuffle
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <cassert>

void printInt(int n)
std::cout << " " << n;


/**
* @brief Function to demonstrate lambda functions.
*
* @param v - the vector to use.
*/
void playingWithLambdaFunctions(std::vector<int> &v)
/* Generate the elements in the vector. The lambda function take a variable
* and increments it everytime. Using mutable so that the value of the
* variable is preserved accross invocations of lambda.*/

std::generate(v.begin(), v.end(), [n = 0]() mutable n = n + 5; return n;);

/* Print the vector using a lambda function. Here the value at a particular
* position is passed as n. This passing is by value. */

std::for_each(v.begin(), v.end(), (int n) std::cout << " " << n; );

/* Other way of printing where we use a unary function for printing. */
std::cerr << "nnPrinting using for_each and unary_functionnn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnPrinting and increasing values of the passed integers. "
"This will not change the sequence as the values are "
"passed by value.nn";

std::for_each(v.begin(), v.end(), (int n)
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnPrinting and increasing values of the passed integers. "
"This will CHANGE the values as we are passing the "
"numbers by reference.nn";

std::for_each(v.begin(), v.end(), (int &n)
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnIncreasing values of the passed integers in the vector. "
"This will CHANGE the values as we are passing the "
"numbers by reference. This time we are also passing the "
"value with which we want to increase.nn";

int increment = 5;
std::for_each(v.begin(), v.end(), [increment](int &n)
std::cout << " CurrentVal(" << n << ")";
n = n + increment; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnConverting all the odd numbers to even by increasing by 1."
" This will CHANGE the values as we are passing the "
"numbers by reference.nn";

std::for_each(v.begin(), v.end(), (int &n) if (n%2) n++; );
std::cerr << "nnPrinting to check if the values changedX.nn";
std::for_each(v.begin(), v.end(), printInt);


/**
* @brief Do some more operations like remove_if, and remove on vector.
*
* @param v - the vector to use.
*/
void otherSequenceOperations(std::vector<int> &v)
/* Remove the elements which are divisible by 4 */
std::sort(v.begin(), v.end());
std::cerr << "nnPrinting to check if the numbers are sorted.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cout << "nnRemoving all the numbers which are divisible by 4";
auto eraseBegin = std::remove_if(v.begin(), v.end(), (const int n)
if (n%4 == 0)
return true;
else
return false;

);

/* std::remove_if moves the removable elements to the end of the list and
* returns the iterator to the begining of the elements to be removed. */
v.erase(eraseBegin, v.end());

std::cerr << "nnPrinting to check if the numbers are removed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cout << "nAdding some more elements";
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(50);

std::cout << "nPrinting the freshly added numbers";
std::for_each(v.begin(), v.end(), printInt);

/* Remove the elements which is equal to 22. */
int numberToRemove = 22;
eraseBegin = std::remove(v.begin(), v.end(), numberToRemove);
v.erase(eraseBegin, v.end());

std::cerr << "nnPrinting to check if 22 was removed. We are counting the "
"presence of the number 22 in the vector. If it is not 0, we "
" exit.nn";
assert(0 == count(v.begin(), v.end(), numberToRemove));
std::for_each(v.begin(), v.end(), printInt);


/**
* @brief Function to demonstrate the std::max_element.
*
* @param v - the vector to be used.
*/
void playWithMaxElement(std::vector <int> &v)
auto maxElementIt = std::max_element(v.begin(), v.end());
auto maxElement = *(maxElementIt);

/* Replace the max element with -1.*/
std::replace(v.begin(), v.end(), maxElement, -1);
std::cout << "nnPrinting after replacing " << maxElement << " with "
<< -1 << "n";
std::for_each(v.begin(), v.end(), printInt);
std::cout << "n";

/* Replace the max element in one line. */

std::replace(v.begin(),
v.end(),
*(std::max_element(v.begin(), v.end())), // Return the position
// of the max element.
100);

std::cout << "nnPrinting after replacing max element with 100 n";
std::for_each(v.begin(), v.end(), printInt);
std::cout << "n";

/* Writing our max function */
int ourMax = 0;

v.push_back(std::numeric_limits<int>::max());
std::for_each(v.begin(), v.end(), [&ourMax](int n)
if (n > ourMax)
ourMax = n;

);
std::cerr << "nOur max is " << ourMax;
assert(ourMax == std::numeric_limits<int>::max());


/**
* @brief Shuffles the vector
*
* @param v - the vector to be shuffled.
*/
void shuffleVector(std::vector <int> &v)
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);
std::cerr << "nnPrinting the shuffled vector.nn";
std::for_each(v.begin(), v.end(), printInt);


int main()
int sizeOfVector = 10;

/* Create the vector. */
std::vector <int> v = std::vector <int>(sizeOfVector);
std::cout << "nPrint the created vector";
std::for_each(v.begin(), v.end(), printInt);

std::cout <<"nDoing some operations in the vector";
playingWithLambdaFunctions(v);
otherSequenceOperations(v);
shuffleVector(v);
playWithMaxElement(v);
return 0;



Makefile is



CPP_STANDARD="c++17"
STANDARD_FLAG="-std=$(CPP_STANDARD)"
OUTPUT_FILE="exe_lambda"
OUTPUT_FLAG=-o $(OUTPUT_FILE)
WARNINGS_FLAG=-Wall -Werror
CPPFLAGS=$(STANDARD_FLAG) $(OUTPUT_FLAG) $(WARNINGS_FLAG)
CC=g++
SOURCE_CODE=lambdas.cc

all:
$(CC) $(CPPFLAGS) $(SOURCE_CODE)

run: all
./$(OUTPUT_FILE)


Output is



Print the created vector 0 0 0 0 0 0 0 0 0 0
Doing some operations in the vector 5 10 15 20 25 30 35 40 45 50



Printing using for_each and unary_function



5 10 15 20 25 30 35 40 45 50



Printing and increasing values of the passed integers. This will not change the sequence as the values are passed by value.



CurrentVal(5) ChangedVal(6) CurrentVal(10) ChangedVal(11) CurrentVal(15) ChangedVal(16) CurrentVal(20) ChangedVal(21) CurrentVal(25) ChangedVal(26) CurrentVal(30) ChangedVal(31) CurrentVal(35) ChangedVal(36) CurrentVal(40) ChangedVal(41) CurrentVal(45) ChangedVal(46) CurrentVal(50) ChangedVal(51)



Printing to check if the values changed.



5 10 15 20 25 30 35 40 45 50



Printing and increasing values of the passed integers. This will CHANGE the values as we are passing the numbers by reference.



CurrentVal(5) ChangedVal(6) CurrentVal(10) ChangedVal(11) CurrentVal(15) ChangedVal(16) CurrentVal(20) ChangedVal(21) CurrentVal(25) ChangedVal(26) CurrentVal(30) ChangedVal(31) CurrentVal(35) ChangedVal(36) CurrentVal(40) ChangedVal(41) CurrentVal(45) ChangedVal(46) CurrentVal(50) ChangedVal(51)



Printing to check if the values changed.



6 11 16 21 26 31 36 41 46 51



Increasing values of the passed integers in the vector. This will CHANGE the values as we are passing the numbers by reference. This time we are also passing the value with which we want to increase.



CurrentVal(6) ChangedVal(11) CurrentVal(11) ChangedVal(16) CurrentVal(16) ChangedVal(21) CurrentVal(21) ChangedVal(26) CurrentVal(26) ChangedVal(31) CurrentVal(31) ChangedVal(36) CurrentVal(36) ChangedVal(41) CurrentVal(41) ChangedVal(46) CurrentVal(46) ChangedVal(51) CurrentVal(51) ChangedVal(56)



Printing to check if the values changed.



11 16 21 26 31 36 41 46 51 56



Converting all the odd numbers to even by increasing by 1. This will CHANGE the values as we are passing the numbers by reference.



Printing to check if the values changedX.



12 16 22 26 32 36 42 46 52 56



Printing to check if the numbers are sorted.



12 16 22 26 32 36 42 46 52 56



Removing all the numbers which are divisible by 4



Printing to check if the numbers are removed.



22 26 42 46
Adding some more elements
Printing the freshly added numbers 22 26 42 46 10 20 30 40 50



Printing to check if 22 was removed. We are counting the presence of the number 22 in the vector. If it is not 0, we exit.



26 42 46 10 20 30 40 50



Printing the shuffled vector.



10 30 46 20 26 40 50 42



Printing after replacing 50 with -1
10 30 46 20 26 40 -1 42



Printing after replacing max element with 100
10 30 100 20 26 40 -1 42



Our max is 2147483647







share|improve this question

















  • 2




    Which version of C++ are you targeting?
    – nwp
    Apr 17 at 12:48










  • You use std:for_each way too much. for (auto& elem: vec) ... is better unless: 1) for_each's last argument is an existing function (like std::for_each(v.begin(), v.end(), printInt);) or 2) you want to iterate over n elements :std::for_each(v.begin(), v.begin()+3, (auto i) std::cout << i*i; );
    – papagaga
    Apr 17 at 13:49










  • A blog on <algorithm> isn't a bad idea, but you must aim for something more consistent than these examples, e.g: which king of "raw loops" you can replace with algorithms, which algorithm you should choose, etc.
    – papagaga
    Apr 17 at 13:53










  • I notice the copyright notice in your code. Which is fine. But I should also note that by posting on this site you are granting a license for the code to be used (see the bottom of the page) contributions licensed under cc by-sa 3.0 Link: cc by-sa 3.0
    – Martin York
    Apr 17 at 15:10











  • Sure you can write an article about these. But you are missing the more important algorithms. std::find() and std::transform(). The std::for_each() has been made a bit redundant with range based for. But I think you would be missing the point by just talking about these. Its the combination of algorithm with iterator that makes them interesting. Look at some of the interesting iterators (not just the container iterators) std::istream_iterator and std::ostream_iterator
    – Martin York
    Apr 17 at 15:15
















up vote
4
down vote

favorite












I have written a cpp program which demonstrates the use of the following functionalities in modern cpp.



Lambda Functions
std::generate
std::vector
std::erase
std::remove_if
std::remove
std::max_element
std::for_each
std::shuffle



I want to understand the following



(1) Have I written the code properly or there are somethings which needs to be improved.



(2) Will it be helpful if I write it as a blog for others. If yes, do I need to add more comments etc to make it more consumable?



 /*
* Copyright Rishi Agrawal <rishi.b.agrawal@gmail.com>
*
* The idea behind this program is to understand how to use the following.
* Lambda Functions
* std::generate
* std::vector
* std::erase
* std::remove_if
* std::remove
* std::max_element
* std::for_each
* std::shuffle
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <cassert>

void printInt(int n)
std::cout << " " << n;


/**
* @brief Function to demonstrate lambda functions.
*
* @param v - the vector to use.
*/
void playingWithLambdaFunctions(std::vector<int> &v)
/* Generate the elements in the vector. The lambda function take a variable
* and increments it everytime. Using mutable so that the value of the
* variable is preserved accross invocations of lambda.*/

std::generate(v.begin(), v.end(), [n = 0]() mutable n = n + 5; return n;);

/* Print the vector using a lambda function. Here the value at a particular
* position is passed as n. This passing is by value. */

std::for_each(v.begin(), v.end(), (int n) std::cout << " " << n; );

/* Other way of printing where we use a unary function for printing. */
std::cerr << "nnPrinting using for_each and unary_functionnn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnPrinting and increasing values of the passed integers. "
"This will not change the sequence as the values are "
"passed by value.nn";

std::for_each(v.begin(), v.end(), (int n)
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnPrinting and increasing values of the passed integers. "
"This will CHANGE the values as we are passing the "
"numbers by reference.nn";

std::for_each(v.begin(), v.end(), (int &n)
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnIncreasing values of the passed integers in the vector. "
"This will CHANGE the values as we are passing the "
"numbers by reference. This time we are also passing the "
"value with which we want to increase.nn";

int increment = 5;
std::for_each(v.begin(), v.end(), [increment](int &n)
std::cout << " CurrentVal(" << n << ")";
n = n + increment; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnConverting all the odd numbers to even by increasing by 1."
" This will CHANGE the values as we are passing the "
"numbers by reference.nn";

std::for_each(v.begin(), v.end(), (int &n) if (n%2) n++; );
std::cerr << "nnPrinting to check if the values changedX.nn";
std::for_each(v.begin(), v.end(), printInt);


/**
* @brief Do some more operations like remove_if, and remove on vector.
*
* @param v - the vector to use.
*/
void otherSequenceOperations(std::vector<int> &v)
/* Remove the elements which are divisible by 4 */
std::sort(v.begin(), v.end());
std::cerr << "nnPrinting to check if the numbers are sorted.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cout << "nnRemoving all the numbers which are divisible by 4";
auto eraseBegin = std::remove_if(v.begin(), v.end(), (const int n)
if (n%4 == 0)
return true;
else
return false;

);

/* std::remove_if moves the removable elements to the end of the list and
* returns the iterator to the begining of the elements to be removed. */
v.erase(eraseBegin, v.end());

std::cerr << "nnPrinting to check if the numbers are removed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cout << "nAdding some more elements";
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(50);

std::cout << "nPrinting the freshly added numbers";
std::for_each(v.begin(), v.end(), printInt);

/* Remove the elements which is equal to 22. */
int numberToRemove = 22;
eraseBegin = std::remove(v.begin(), v.end(), numberToRemove);
v.erase(eraseBegin, v.end());

std::cerr << "nnPrinting to check if 22 was removed. We are counting the "
"presence of the number 22 in the vector. If it is not 0, we "
" exit.nn";
assert(0 == count(v.begin(), v.end(), numberToRemove));
std::for_each(v.begin(), v.end(), printInt);


/**
* @brief Function to demonstrate the std::max_element.
*
* @param v - the vector to be used.
*/
void playWithMaxElement(std::vector <int> &v)
auto maxElementIt = std::max_element(v.begin(), v.end());
auto maxElement = *(maxElementIt);

/* Replace the max element with -1.*/
std::replace(v.begin(), v.end(), maxElement, -1);
std::cout << "nnPrinting after replacing " << maxElement << " with "
<< -1 << "n";
std::for_each(v.begin(), v.end(), printInt);
std::cout << "n";

/* Replace the max element in one line. */

std::replace(v.begin(),
v.end(),
*(std::max_element(v.begin(), v.end())), // Return the position
// of the max element.
100);

std::cout << "nnPrinting after replacing max element with 100 n";
std::for_each(v.begin(), v.end(), printInt);
std::cout << "n";

/* Writing our max function */
int ourMax = 0;

v.push_back(std::numeric_limits<int>::max());
std::for_each(v.begin(), v.end(), [&ourMax](int n)
if (n > ourMax)
ourMax = n;

);
std::cerr << "nOur max is " << ourMax;
assert(ourMax == std::numeric_limits<int>::max());


/**
* @brief Shuffles the vector
*
* @param v - the vector to be shuffled.
*/
void shuffleVector(std::vector <int> &v)
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);
std::cerr << "nnPrinting the shuffled vector.nn";
std::for_each(v.begin(), v.end(), printInt);


int main()
int sizeOfVector = 10;

/* Create the vector. */
std::vector <int> v = std::vector <int>(sizeOfVector);
std::cout << "nPrint the created vector";
std::for_each(v.begin(), v.end(), printInt);

std::cout <<"nDoing some operations in the vector";
playingWithLambdaFunctions(v);
otherSequenceOperations(v);
shuffleVector(v);
playWithMaxElement(v);
return 0;



Makefile is



CPP_STANDARD="c++17"
STANDARD_FLAG="-std=$(CPP_STANDARD)"
OUTPUT_FILE="exe_lambda"
OUTPUT_FLAG=-o $(OUTPUT_FILE)
WARNINGS_FLAG=-Wall -Werror
CPPFLAGS=$(STANDARD_FLAG) $(OUTPUT_FLAG) $(WARNINGS_FLAG)
CC=g++
SOURCE_CODE=lambdas.cc

all:
$(CC) $(CPPFLAGS) $(SOURCE_CODE)

run: all
./$(OUTPUT_FILE)


Output is



Print the created vector 0 0 0 0 0 0 0 0 0 0
Doing some operations in the vector 5 10 15 20 25 30 35 40 45 50



Printing using for_each and unary_function



5 10 15 20 25 30 35 40 45 50



Printing and increasing values of the passed integers. This will not change the sequence as the values are passed by value.



CurrentVal(5) ChangedVal(6) CurrentVal(10) ChangedVal(11) CurrentVal(15) ChangedVal(16) CurrentVal(20) ChangedVal(21) CurrentVal(25) ChangedVal(26) CurrentVal(30) ChangedVal(31) CurrentVal(35) ChangedVal(36) CurrentVal(40) ChangedVal(41) CurrentVal(45) ChangedVal(46) CurrentVal(50) ChangedVal(51)



Printing to check if the values changed.



5 10 15 20 25 30 35 40 45 50



Printing and increasing values of the passed integers. This will CHANGE the values as we are passing the numbers by reference.



CurrentVal(5) ChangedVal(6) CurrentVal(10) ChangedVal(11) CurrentVal(15) ChangedVal(16) CurrentVal(20) ChangedVal(21) CurrentVal(25) ChangedVal(26) CurrentVal(30) ChangedVal(31) CurrentVal(35) ChangedVal(36) CurrentVal(40) ChangedVal(41) CurrentVal(45) ChangedVal(46) CurrentVal(50) ChangedVal(51)



Printing to check if the values changed.



6 11 16 21 26 31 36 41 46 51



Increasing values of the passed integers in the vector. This will CHANGE the values as we are passing the numbers by reference. This time we are also passing the value with which we want to increase.



CurrentVal(6) ChangedVal(11) CurrentVal(11) ChangedVal(16) CurrentVal(16) ChangedVal(21) CurrentVal(21) ChangedVal(26) CurrentVal(26) ChangedVal(31) CurrentVal(31) ChangedVal(36) CurrentVal(36) ChangedVal(41) CurrentVal(41) ChangedVal(46) CurrentVal(46) ChangedVal(51) CurrentVal(51) ChangedVal(56)



Printing to check if the values changed.



11 16 21 26 31 36 41 46 51 56



Converting all the odd numbers to even by increasing by 1. This will CHANGE the values as we are passing the numbers by reference.



Printing to check if the values changedX.



12 16 22 26 32 36 42 46 52 56



Printing to check if the numbers are sorted.



12 16 22 26 32 36 42 46 52 56



Removing all the numbers which are divisible by 4



Printing to check if the numbers are removed.



22 26 42 46
Adding some more elements
Printing the freshly added numbers 22 26 42 46 10 20 30 40 50



Printing to check if 22 was removed. We are counting the presence of the number 22 in the vector. If it is not 0, we exit.



26 42 46 10 20 30 40 50



Printing the shuffled vector.



10 30 46 20 26 40 50 42



Printing after replacing 50 with -1
10 30 46 20 26 40 -1 42



Printing after replacing max element with 100
10 30 100 20 26 40 -1 42



Our max is 2147483647







share|improve this question

















  • 2




    Which version of C++ are you targeting?
    – nwp
    Apr 17 at 12:48










  • You use std:for_each way too much. for (auto& elem: vec) ... is better unless: 1) for_each's last argument is an existing function (like std::for_each(v.begin(), v.end(), printInt);) or 2) you want to iterate over n elements :std::for_each(v.begin(), v.begin()+3, (auto i) std::cout << i*i; );
    – papagaga
    Apr 17 at 13:49










  • A blog on <algorithm> isn't a bad idea, but you must aim for something more consistent than these examples, e.g: which king of "raw loops" you can replace with algorithms, which algorithm you should choose, etc.
    – papagaga
    Apr 17 at 13:53










  • I notice the copyright notice in your code. Which is fine. But I should also note that by posting on this site you are granting a license for the code to be used (see the bottom of the page) contributions licensed under cc by-sa 3.0 Link: cc by-sa 3.0
    – Martin York
    Apr 17 at 15:10











  • Sure you can write an article about these. But you are missing the more important algorithms. std::find() and std::transform(). The std::for_each() has been made a bit redundant with range based for. But I think you would be missing the point by just talking about these. Its the combination of algorithm with iterator that makes them interesting. Look at some of the interesting iterators (not just the container iterators) std::istream_iterator and std::ostream_iterator
    – Martin York
    Apr 17 at 15:15












up vote
4
down vote

favorite









up vote
4
down vote

favorite











I have written a cpp program which demonstrates the use of the following functionalities in modern cpp.



Lambda Functions
std::generate
std::vector
std::erase
std::remove_if
std::remove
std::max_element
std::for_each
std::shuffle



I want to understand the following



(1) Have I written the code properly or there are somethings which needs to be improved.



(2) Will it be helpful if I write it as a blog for others. If yes, do I need to add more comments etc to make it more consumable?



 /*
* Copyright Rishi Agrawal <rishi.b.agrawal@gmail.com>
*
* The idea behind this program is to understand how to use the following.
* Lambda Functions
* std::generate
* std::vector
* std::erase
* std::remove_if
* std::remove
* std::max_element
* std::for_each
* std::shuffle
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <cassert>

void printInt(int n)
std::cout << " " << n;


/**
* @brief Function to demonstrate lambda functions.
*
* @param v - the vector to use.
*/
void playingWithLambdaFunctions(std::vector<int> &v)
/* Generate the elements in the vector. The lambda function take a variable
* and increments it everytime. Using mutable so that the value of the
* variable is preserved accross invocations of lambda.*/

std::generate(v.begin(), v.end(), [n = 0]() mutable n = n + 5; return n;);

/* Print the vector using a lambda function. Here the value at a particular
* position is passed as n. This passing is by value. */

std::for_each(v.begin(), v.end(), (int n) std::cout << " " << n; );

/* Other way of printing where we use a unary function for printing. */
std::cerr << "nnPrinting using for_each and unary_functionnn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnPrinting and increasing values of the passed integers. "
"This will not change the sequence as the values are "
"passed by value.nn";

std::for_each(v.begin(), v.end(), (int n)
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnPrinting and increasing values of the passed integers. "
"This will CHANGE the values as we are passing the "
"numbers by reference.nn";

std::for_each(v.begin(), v.end(), (int &n)
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnIncreasing values of the passed integers in the vector. "
"This will CHANGE the values as we are passing the "
"numbers by reference. This time we are also passing the "
"value with which we want to increase.nn";

int increment = 5;
std::for_each(v.begin(), v.end(), [increment](int &n)
std::cout << " CurrentVal(" << n << ")";
n = n + increment; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnConverting all the odd numbers to even by increasing by 1."
" This will CHANGE the values as we are passing the "
"numbers by reference.nn";

std::for_each(v.begin(), v.end(), (int &n) if (n%2) n++; );
std::cerr << "nnPrinting to check if the values changedX.nn";
std::for_each(v.begin(), v.end(), printInt);


/**
* @brief Do some more operations like remove_if, and remove on vector.
*
* @param v - the vector to use.
*/
void otherSequenceOperations(std::vector<int> &v)
/* Remove the elements which are divisible by 4 */
std::sort(v.begin(), v.end());
std::cerr << "nnPrinting to check if the numbers are sorted.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cout << "nnRemoving all the numbers which are divisible by 4";
auto eraseBegin = std::remove_if(v.begin(), v.end(), (const int n)
if (n%4 == 0)
return true;
else
return false;

);

/* std::remove_if moves the removable elements to the end of the list and
* returns the iterator to the begining of the elements to be removed. */
v.erase(eraseBegin, v.end());

std::cerr << "nnPrinting to check if the numbers are removed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cout << "nAdding some more elements";
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(50);

std::cout << "nPrinting the freshly added numbers";
std::for_each(v.begin(), v.end(), printInt);

/* Remove the elements which is equal to 22. */
int numberToRemove = 22;
eraseBegin = std::remove(v.begin(), v.end(), numberToRemove);
v.erase(eraseBegin, v.end());

std::cerr << "nnPrinting to check if 22 was removed. We are counting the "
"presence of the number 22 in the vector. If it is not 0, we "
" exit.nn";
assert(0 == count(v.begin(), v.end(), numberToRemove));
std::for_each(v.begin(), v.end(), printInt);


/**
* @brief Function to demonstrate the std::max_element.
*
* @param v - the vector to be used.
*/
void playWithMaxElement(std::vector <int> &v)
auto maxElementIt = std::max_element(v.begin(), v.end());
auto maxElement = *(maxElementIt);

/* Replace the max element with -1.*/
std::replace(v.begin(), v.end(), maxElement, -1);
std::cout << "nnPrinting after replacing " << maxElement << " with "
<< -1 << "n";
std::for_each(v.begin(), v.end(), printInt);
std::cout << "n";

/* Replace the max element in one line. */

std::replace(v.begin(),
v.end(),
*(std::max_element(v.begin(), v.end())), // Return the position
// of the max element.
100);

std::cout << "nnPrinting after replacing max element with 100 n";
std::for_each(v.begin(), v.end(), printInt);
std::cout << "n";

/* Writing our max function */
int ourMax = 0;

v.push_back(std::numeric_limits<int>::max());
std::for_each(v.begin(), v.end(), [&ourMax](int n)
if (n > ourMax)
ourMax = n;

);
std::cerr << "nOur max is " << ourMax;
assert(ourMax == std::numeric_limits<int>::max());


/**
* @brief Shuffles the vector
*
* @param v - the vector to be shuffled.
*/
void shuffleVector(std::vector <int> &v)
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);
std::cerr << "nnPrinting the shuffled vector.nn";
std::for_each(v.begin(), v.end(), printInt);


int main()
int sizeOfVector = 10;

/* Create the vector. */
std::vector <int> v = std::vector <int>(sizeOfVector);
std::cout << "nPrint the created vector";
std::for_each(v.begin(), v.end(), printInt);

std::cout <<"nDoing some operations in the vector";
playingWithLambdaFunctions(v);
otherSequenceOperations(v);
shuffleVector(v);
playWithMaxElement(v);
return 0;



Makefile is



CPP_STANDARD="c++17"
STANDARD_FLAG="-std=$(CPP_STANDARD)"
OUTPUT_FILE="exe_lambda"
OUTPUT_FLAG=-o $(OUTPUT_FILE)
WARNINGS_FLAG=-Wall -Werror
CPPFLAGS=$(STANDARD_FLAG) $(OUTPUT_FLAG) $(WARNINGS_FLAG)
CC=g++
SOURCE_CODE=lambdas.cc

all:
$(CC) $(CPPFLAGS) $(SOURCE_CODE)

run: all
./$(OUTPUT_FILE)


Output is



Print the created vector 0 0 0 0 0 0 0 0 0 0
Doing some operations in the vector 5 10 15 20 25 30 35 40 45 50



Printing using for_each and unary_function



5 10 15 20 25 30 35 40 45 50



Printing and increasing values of the passed integers. This will not change the sequence as the values are passed by value.



CurrentVal(5) ChangedVal(6) CurrentVal(10) ChangedVal(11) CurrentVal(15) ChangedVal(16) CurrentVal(20) ChangedVal(21) CurrentVal(25) ChangedVal(26) CurrentVal(30) ChangedVal(31) CurrentVal(35) ChangedVal(36) CurrentVal(40) ChangedVal(41) CurrentVal(45) ChangedVal(46) CurrentVal(50) ChangedVal(51)



Printing to check if the values changed.



5 10 15 20 25 30 35 40 45 50



Printing and increasing values of the passed integers. This will CHANGE the values as we are passing the numbers by reference.



CurrentVal(5) ChangedVal(6) CurrentVal(10) ChangedVal(11) CurrentVal(15) ChangedVal(16) CurrentVal(20) ChangedVal(21) CurrentVal(25) ChangedVal(26) CurrentVal(30) ChangedVal(31) CurrentVal(35) ChangedVal(36) CurrentVal(40) ChangedVal(41) CurrentVal(45) ChangedVal(46) CurrentVal(50) ChangedVal(51)



Printing to check if the values changed.



6 11 16 21 26 31 36 41 46 51



Increasing values of the passed integers in the vector. This will CHANGE the values as we are passing the numbers by reference. This time we are also passing the value with which we want to increase.



CurrentVal(6) ChangedVal(11) CurrentVal(11) ChangedVal(16) CurrentVal(16) ChangedVal(21) CurrentVal(21) ChangedVal(26) CurrentVal(26) ChangedVal(31) CurrentVal(31) ChangedVal(36) CurrentVal(36) ChangedVal(41) CurrentVal(41) ChangedVal(46) CurrentVal(46) ChangedVal(51) CurrentVal(51) ChangedVal(56)



Printing to check if the values changed.



11 16 21 26 31 36 41 46 51 56



Converting all the odd numbers to even by increasing by 1. This will CHANGE the values as we are passing the numbers by reference.



Printing to check if the values changedX.



12 16 22 26 32 36 42 46 52 56



Printing to check if the numbers are sorted.



12 16 22 26 32 36 42 46 52 56



Removing all the numbers which are divisible by 4



Printing to check if the numbers are removed.



22 26 42 46
Adding some more elements
Printing the freshly added numbers 22 26 42 46 10 20 30 40 50



Printing to check if 22 was removed. We are counting the presence of the number 22 in the vector. If it is not 0, we exit.



26 42 46 10 20 30 40 50



Printing the shuffled vector.



10 30 46 20 26 40 50 42



Printing after replacing 50 with -1
10 30 46 20 26 40 -1 42



Printing after replacing max element with 100
10 30 100 20 26 40 -1 42



Our max is 2147483647







share|improve this question













I have written a cpp program which demonstrates the use of the following functionalities in modern cpp.



Lambda Functions
std::generate
std::vector
std::erase
std::remove_if
std::remove
std::max_element
std::for_each
std::shuffle



I want to understand the following



(1) Have I written the code properly or there are somethings which needs to be improved.



(2) Will it be helpful if I write it as a blog for others. If yes, do I need to add more comments etc to make it more consumable?



 /*
* Copyright Rishi Agrawal <rishi.b.agrawal@gmail.com>
*
* The idea behind this program is to understand how to use the following.
* Lambda Functions
* std::generate
* std::vector
* std::erase
* std::remove_if
* std::remove
* std::max_element
* std::for_each
* std::shuffle
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <cassert>

void printInt(int n)
std::cout << " " << n;


/**
* @brief Function to demonstrate lambda functions.
*
* @param v - the vector to use.
*/
void playingWithLambdaFunctions(std::vector<int> &v)
/* Generate the elements in the vector. The lambda function take a variable
* and increments it everytime. Using mutable so that the value of the
* variable is preserved accross invocations of lambda.*/

std::generate(v.begin(), v.end(), [n = 0]() mutable n = n + 5; return n;);

/* Print the vector using a lambda function. Here the value at a particular
* position is passed as n. This passing is by value. */

std::for_each(v.begin(), v.end(), (int n) std::cout << " " << n; );

/* Other way of printing where we use a unary function for printing. */
std::cerr << "nnPrinting using for_each and unary_functionnn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnPrinting and increasing values of the passed integers. "
"This will not change the sequence as the values are "
"passed by value.nn";

std::for_each(v.begin(), v.end(), (int n)
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnPrinting and increasing values of the passed integers. "
"This will CHANGE the values as we are passing the "
"numbers by reference.nn";

std::for_each(v.begin(), v.end(), (int &n)
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnIncreasing values of the passed integers in the vector. "
"This will CHANGE the values as we are passing the "
"numbers by reference. This time we are also passing the "
"value with which we want to increase.nn";

int increment = 5;
std::for_each(v.begin(), v.end(), [increment](int &n)
std::cout << " CurrentVal(" << n << ")";
n = n + increment; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);

std::cerr << "nnPrinting to check if the values changed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cerr << "nnConverting all the odd numbers to even by increasing by 1."
" This will CHANGE the values as we are passing the "
"numbers by reference.nn";

std::for_each(v.begin(), v.end(), (int &n) if (n%2) n++; );
std::cerr << "nnPrinting to check if the values changedX.nn";
std::for_each(v.begin(), v.end(), printInt);


/**
* @brief Do some more operations like remove_if, and remove on vector.
*
* @param v - the vector to use.
*/
void otherSequenceOperations(std::vector<int> &v)
/* Remove the elements which are divisible by 4 */
std::sort(v.begin(), v.end());
std::cerr << "nnPrinting to check if the numbers are sorted.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cout << "nnRemoving all the numbers which are divisible by 4";
auto eraseBegin = std::remove_if(v.begin(), v.end(), (const int n)
if (n%4 == 0)
return true;
else
return false;

);

/* std::remove_if moves the removable elements to the end of the list and
* returns the iterator to the begining of the elements to be removed. */
v.erase(eraseBegin, v.end());

std::cerr << "nnPrinting to check if the numbers are removed.nn";
std::for_each(v.begin(), v.end(), printInt);

std::cout << "nAdding some more elements";
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(50);

std::cout << "nPrinting the freshly added numbers";
std::for_each(v.begin(), v.end(), printInt);

/* Remove the elements which is equal to 22. */
int numberToRemove = 22;
eraseBegin = std::remove(v.begin(), v.end(), numberToRemove);
v.erase(eraseBegin, v.end());

std::cerr << "nnPrinting to check if 22 was removed. We are counting the "
"presence of the number 22 in the vector. If it is not 0, we "
" exit.nn";
assert(0 == count(v.begin(), v.end(), numberToRemove));
std::for_each(v.begin(), v.end(), printInt);


/**
* @brief Function to demonstrate the std::max_element.
*
* @param v - the vector to be used.
*/
void playWithMaxElement(std::vector <int> &v)
auto maxElementIt = std::max_element(v.begin(), v.end());
auto maxElement = *(maxElementIt);

/* Replace the max element with -1.*/
std::replace(v.begin(), v.end(), maxElement, -1);
std::cout << "nnPrinting after replacing " << maxElement << " with "
<< -1 << "n";
std::for_each(v.begin(), v.end(), printInt);
std::cout << "n";

/* Replace the max element in one line. */

std::replace(v.begin(),
v.end(),
*(std::max_element(v.begin(), v.end())), // Return the position
// of the max element.
100);

std::cout << "nnPrinting after replacing max element with 100 n";
std::for_each(v.begin(), v.end(), printInt);
std::cout << "n";

/* Writing our max function */
int ourMax = 0;

v.push_back(std::numeric_limits<int>::max());
std::for_each(v.begin(), v.end(), [&ourMax](int n)
if (n > ourMax)
ourMax = n;

);
std::cerr << "nOur max is " << ourMax;
assert(ourMax == std::numeric_limits<int>::max());


/**
* @brief Shuffles the vector
*
* @param v - the vector to be shuffled.
*/
void shuffleVector(std::vector <int> &v)
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);
std::cerr << "nnPrinting the shuffled vector.nn";
std::for_each(v.begin(), v.end(), printInt);


int main()
int sizeOfVector = 10;

/* Create the vector. */
std::vector <int> v = std::vector <int>(sizeOfVector);
std::cout << "nPrint the created vector";
std::for_each(v.begin(), v.end(), printInt);

std::cout <<"nDoing some operations in the vector";
playingWithLambdaFunctions(v);
otherSequenceOperations(v);
shuffleVector(v);
playWithMaxElement(v);
return 0;



Makefile is



CPP_STANDARD="c++17"
STANDARD_FLAG="-std=$(CPP_STANDARD)"
OUTPUT_FILE="exe_lambda"
OUTPUT_FLAG=-o $(OUTPUT_FILE)
WARNINGS_FLAG=-Wall -Werror
CPPFLAGS=$(STANDARD_FLAG) $(OUTPUT_FLAG) $(WARNINGS_FLAG)
CC=g++
SOURCE_CODE=lambdas.cc

all:
$(CC) $(CPPFLAGS) $(SOURCE_CODE)

run: all
./$(OUTPUT_FILE)


Output is



Print the created vector 0 0 0 0 0 0 0 0 0 0
Doing some operations in the vector 5 10 15 20 25 30 35 40 45 50



Printing using for_each and unary_function



5 10 15 20 25 30 35 40 45 50



Printing and increasing values of the passed integers. This will not change the sequence as the values are passed by value.



CurrentVal(5) ChangedVal(6) CurrentVal(10) ChangedVal(11) CurrentVal(15) ChangedVal(16) CurrentVal(20) ChangedVal(21) CurrentVal(25) ChangedVal(26) CurrentVal(30) ChangedVal(31) CurrentVal(35) ChangedVal(36) CurrentVal(40) ChangedVal(41) CurrentVal(45) ChangedVal(46) CurrentVal(50) ChangedVal(51)



Printing to check if the values changed.



5 10 15 20 25 30 35 40 45 50



Printing and increasing values of the passed integers. This will CHANGE the values as we are passing the numbers by reference.



CurrentVal(5) ChangedVal(6) CurrentVal(10) ChangedVal(11) CurrentVal(15) ChangedVal(16) CurrentVal(20) ChangedVal(21) CurrentVal(25) ChangedVal(26) CurrentVal(30) ChangedVal(31) CurrentVal(35) ChangedVal(36) CurrentVal(40) ChangedVal(41) CurrentVal(45) ChangedVal(46) CurrentVal(50) ChangedVal(51)



Printing to check if the values changed.



6 11 16 21 26 31 36 41 46 51



Increasing values of the passed integers in the vector. This will CHANGE the values as we are passing the numbers by reference. This time we are also passing the value with which we want to increase.



CurrentVal(6) ChangedVal(11) CurrentVal(11) ChangedVal(16) CurrentVal(16) ChangedVal(21) CurrentVal(21) ChangedVal(26) CurrentVal(26) ChangedVal(31) CurrentVal(31) ChangedVal(36) CurrentVal(36) ChangedVal(41) CurrentVal(41) ChangedVal(46) CurrentVal(46) ChangedVal(51) CurrentVal(51) ChangedVal(56)



Printing to check if the values changed.



11 16 21 26 31 36 41 46 51 56



Converting all the odd numbers to even by increasing by 1. This will CHANGE the values as we are passing the numbers by reference.



Printing to check if the values changedX.



12 16 22 26 32 36 42 46 52 56



Printing to check if the numbers are sorted.



12 16 22 26 32 36 42 46 52 56



Removing all the numbers which are divisible by 4



Printing to check if the numbers are removed.



22 26 42 46
Adding some more elements
Printing the freshly added numbers 22 26 42 46 10 20 30 40 50



Printing to check if 22 was removed. We are counting the presence of the number 22 in the vector. If it is not 0, we exit.



26 42 46 10 20 30 40 50



Printing the shuffled vector.



10 30 46 20 26 40 50 42



Printing after replacing 50 with -1
10 30 46 20 26 40 -1 42



Printing after replacing max element with 100
10 30 100 20 26 40 -1 42



Our max is 2147483647









share|improve this question












share|improve this question




share|improve this question








edited Apr 17 at 12:44
























asked Apr 17 at 12:33









Rishi Agrawal

385




385







  • 2




    Which version of C++ are you targeting?
    – nwp
    Apr 17 at 12:48










  • You use std:for_each way too much. for (auto& elem: vec) ... is better unless: 1) for_each's last argument is an existing function (like std::for_each(v.begin(), v.end(), printInt);) or 2) you want to iterate over n elements :std::for_each(v.begin(), v.begin()+3, (auto i) std::cout << i*i; );
    – papagaga
    Apr 17 at 13:49










  • A blog on <algorithm> isn't a bad idea, but you must aim for something more consistent than these examples, e.g: which king of "raw loops" you can replace with algorithms, which algorithm you should choose, etc.
    – papagaga
    Apr 17 at 13:53










  • I notice the copyright notice in your code. Which is fine. But I should also note that by posting on this site you are granting a license for the code to be used (see the bottom of the page) contributions licensed under cc by-sa 3.0 Link: cc by-sa 3.0
    – Martin York
    Apr 17 at 15:10











  • Sure you can write an article about these. But you are missing the more important algorithms. std::find() and std::transform(). The std::for_each() has been made a bit redundant with range based for. But I think you would be missing the point by just talking about these. Its the combination of algorithm with iterator that makes them interesting. Look at some of the interesting iterators (not just the container iterators) std::istream_iterator and std::ostream_iterator
    – Martin York
    Apr 17 at 15:15












  • 2




    Which version of C++ are you targeting?
    – nwp
    Apr 17 at 12:48










  • You use std:for_each way too much. for (auto& elem: vec) ... is better unless: 1) for_each's last argument is an existing function (like std::for_each(v.begin(), v.end(), printInt);) or 2) you want to iterate over n elements :std::for_each(v.begin(), v.begin()+3, (auto i) std::cout << i*i; );
    – papagaga
    Apr 17 at 13:49










  • A blog on <algorithm> isn't a bad idea, but you must aim for something more consistent than these examples, e.g: which king of "raw loops" you can replace with algorithms, which algorithm you should choose, etc.
    – papagaga
    Apr 17 at 13:53










  • I notice the copyright notice in your code. Which is fine. But I should also note that by posting on this site you are granting a license for the code to be used (see the bottom of the page) contributions licensed under cc by-sa 3.0 Link: cc by-sa 3.0
    – Martin York
    Apr 17 at 15:10











  • Sure you can write an article about these. But you are missing the more important algorithms. std::find() and std::transform(). The std::for_each() has been made a bit redundant with range based for. But I think you would be missing the point by just talking about these. Its the combination of algorithm with iterator that makes them interesting. Look at some of the interesting iterators (not just the container iterators) std::istream_iterator and std::ostream_iterator
    – Martin York
    Apr 17 at 15:15







2




2




Which version of C++ are you targeting?
– nwp
Apr 17 at 12:48




Which version of C++ are you targeting?
– nwp
Apr 17 at 12:48












You use std:for_each way too much. for (auto& elem: vec) ... is better unless: 1) for_each's last argument is an existing function (like std::for_each(v.begin(), v.end(), printInt);) or 2) you want to iterate over n elements :std::for_each(v.begin(), v.begin()+3, (auto i) std::cout << i*i; );
– papagaga
Apr 17 at 13:49




You use std:for_each way too much. for (auto& elem: vec) ... is better unless: 1) for_each's last argument is an existing function (like std::for_each(v.begin(), v.end(), printInt);) or 2) you want to iterate over n elements :std::for_each(v.begin(), v.begin()+3, (auto i) std::cout << i*i; );
– papagaga
Apr 17 at 13:49












A blog on <algorithm> isn't a bad idea, but you must aim for something more consistent than these examples, e.g: which king of "raw loops" you can replace with algorithms, which algorithm you should choose, etc.
– papagaga
Apr 17 at 13:53




A blog on <algorithm> isn't a bad idea, but you must aim for something more consistent than these examples, e.g: which king of "raw loops" you can replace with algorithms, which algorithm you should choose, etc.
– papagaga
Apr 17 at 13:53












I notice the copyright notice in your code. Which is fine. But I should also note that by posting on this site you are granting a license for the code to be used (see the bottom of the page) contributions licensed under cc by-sa 3.0 Link: cc by-sa 3.0
– Martin York
Apr 17 at 15:10





I notice the copyright notice in your code. Which is fine. But I should also note that by posting on this site you are granting a license for the code to be used (see the bottom of the page) contributions licensed under cc by-sa 3.0 Link: cc by-sa 3.0
– Martin York
Apr 17 at 15:10













Sure you can write an article about these. But you are missing the more important algorithms. std::find() and std::transform(). The std::for_each() has been made a bit redundant with range based for. But I think you would be missing the point by just talking about these. Its the combination of algorithm with iterator that makes them interesting. Look at some of the interesting iterators (not just the container iterators) std::istream_iterator and std::ostream_iterator
– Martin York
Apr 17 at 15:15




Sure you can write an article about these. But you are missing the more important algorithms. std::find() and std::transform(). The std::for_each() has been made a bit redundant with range based for. But I think you would be missing the point by just talking about these. Its the combination of algorithm with iterator that makes them interesting. Look at some of the interesting iterators (not just the container iterators) std::istream_iterator and std::ostream_iterator
– Martin York
Apr 17 at 15:15










1 Answer
1






active

oldest

votes

















up vote
5
down vote



accepted










For such a simple case this Makefile is a waste.



It can be replaced with:



> rm Makefile
> export CXXFLAGS ="-std=c++17 -Wall -Werror"
> make lambdas


The standard implicit rules of Make will build lambdas from lambdas.cc



Sure Good use:



 std::generate(v.begin(), v.end(), [n = 0]() mutable n = n + 5; return n;);


Probably not a good example:



 std::for_each(v.begin(), v.end(),
(int n) std::cout << " " << n; );


I like (as it shows intent better).



 std::copy(v.begin(), v.end(),
std::ostream_iterator<int>(std::cout, "n");


But I think the modern (and idiomatic) form is:



 for(auto const& item: v) 
std::cout << v << "n";



I like this even less:



 std::for_each(v.begin(), v.end(), printInt);


You could have just as easily written:



 printVect(v);


Here the lambda is too large. At this size you should be creating a functor. If you have to do it inline then don't indent it all the way to the right like that. Some people don't have wide screens.



 std::for_each(v.begin(), v.end(), (int n) 
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);


OK. I'll ignore the rest of the for_each as I think we have covered the main points.



Good:



 std::sort(v.begin(), v.end());


Erase/Remove is a good example. Though this lambda is terrible.



 auto eraseBegin = std::remove_if(v.begin(), v.end(), (const int n) 
if (n%4 == 0)
return true;
else
return false;

);


Don't use a if statement to generate a true/false result. That value is an inherent part of the expression.



 if (n%4 == 0) 
return true;
else
return false;



Can be simplified to:



 return n%4 == 0;


Now that's a good lambda.



 auto eraseBegin = std::remove_if(v.begin(), v.end(),
(const int n) return n%4 == 0;);
v.erase(eraseBegin, v.end());


Good:



 eraseBegin = std::remove(v.begin(), v.end(), numberToRemove);
v.erase(eraseBegin, v.end());


Good:



 auto maxElementIt = std::max_element(v.begin(), v.end());
auto maxElement = *(maxElementIt);


Good:



 std::replace(v.begin(), v.end(), maxElement, -1);


I like this: it's a good simple example of random usage.



void shuffleVector(std::vector <int> &v) 
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);
std::cerr << "nnPrinting the shuffled vector.nn";
std::for_each(v.begin(), v.end(), printInt);



That random number generator is very expensive to create. And once you have it up and running, why recreate it each time? So I would make the random number stuff static inside the function:



void shuffleVector(std::vector <int> &v) {
static std::random_device rd;
static std::mt19937 g(rd());


As a side note:



The standard introduced std::begin() and std::end(). So you can now use these rather than the member versions. This allows you to generalize the code so it can be used on any container type (including arrays).



using std::begin;
using std::end;
std::for_each(begin(v), end(v), doStuff);


Now you don't need to care about the type of v. You can even change it to a C-Array and it would still work.






share|improve this answer























  • I apologize if I'm wrong but beyond being expensive to create doesn't a PRNG need to be a single reusable instance like you suggested in order to work properly?
    – bruglesco
    Apr 17 at 22:09










  • @bruglesco The new random allows you to create multiple random number generators and they should work independently (and I hear well). But in my personal opinion: One should be enough for an app.
    – Martin York
    Apr 17 at 23:06










  • Doesn’t non-member begin and end need to be unqualified to really be universal? std::begin will work for a primitive array and std collections, but not for custom collections and ranges from 3rd party libraries that are not in the std namespace. You need to use ADL, just like with swap.
    – JDługosz
    Apr 18 at 6:30










  • Thanks a lot for reviewing in so much detail. Thanks for the useful comments. I will incorporate the suggested changes. I got to learn a lot. :-)
    – Rishi Agrawal
    Apr 18 at 7:24










  • @JDługosz I see what you are saying. Do be honest I had not thought about that, but its a good point. You are saying for types that don't have a begin/end method but do have specializations of the begin/end free standing methods. Personally I would hope that if you implement iterator like semantics for your object you also implement the begin/end method, but I can see how it is not required.
    – Martin York
    Apr 18 at 16:54











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192284%2fexamples-of-lambda-functions-stdfor-each-max-element-remove-if-etc%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
5
down vote



accepted










For such a simple case this Makefile is a waste.



It can be replaced with:



> rm Makefile
> export CXXFLAGS ="-std=c++17 -Wall -Werror"
> make lambdas


The standard implicit rules of Make will build lambdas from lambdas.cc



Sure Good use:



 std::generate(v.begin(), v.end(), [n = 0]() mutable n = n + 5; return n;);


Probably not a good example:



 std::for_each(v.begin(), v.end(),
(int n) std::cout << " " << n; );


I like (as it shows intent better).



 std::copy(v.begin(), v.end(),
std::ostream_iterator<int>(std::cout, "n");


But I think the modern (and idiomatic) form is:



 for(auto const& item: v) 
std::cout << v << "n";



I like this even less:



 std::for_each(v.begin(), v.end(), printInt);


You could have just as easily written:



 printVect(v);


Here the lambda is too large. At this size you should be creating a functor. If you have to do it inline then don't indent it all the way to the right like that. Some people don't have wide screens.



 std::for_each(v.begin(), v.end(), (int n) 
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);


OK. I'll ignore the rest of the for_each as I think we have covered the main points.



Good:



 std::sort(v.begin(), v.end());


Erase/Remove is a good example. Though this lambda is terrible.



 auto eraseBegin = std::remove_if(v.begin(), v.end(), (const int n) 
if (n%4 == 0)
return true;
else
return false;

);


Don't use a if statement to generate a true/false result. That value is an inherent part of the expression.



 if (n%4 == 0) 
return true;
else
return false;



Can be simplified to:



 return n%4 == 0;


Now that's a good lambda.



 auto eraseBegin = std::remove_if(v.begin(), v.end(),
(const int n) return n%4 == 0;);
v.erase(eraseBegin, v.end());


Good:



 eraseBegin = std::remove(v.begin(), v.end(), numberToRemove);
v.erase(eraseBegin, v.end());


Good:



 auto maxElementIt = std::max_element(v.begin(), v.end());
auto maxElement = *(maxElementIt);


Good:



 std::replace(v.begin(), v.end(), maxElement, -1);


I like this: it's a good simple example of random usage.



void shuffleVector(std::vector <int> &v) 
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);
std::cerr << "nnPrinting the shuffled vector.nn";
std::for_each(v.begin(), v.end(), printInt);



That random number generator is very expensive to create. And once you have it up and running, why recreate it each time? So I would make the random number stuff static inside the function:



void shuffleVector(std::vector <int> &v) {
static std::random_device rd;
static std::mt19937 g(rd());


As a side note:



The standard introduced std::begin() and std::end(). So you can now use these rather than the member versions. This allows you to generalize the code so it can be used on any container type (including arrays).



using std::begin;
using std::end;
std::for_each(begin(v), end(v), doStuff);


Now you don't need to care about the type of v. You can even change it to a C-Array and it would still work.






share|improve this answer























  • I apologize if I'm wrong but beyond being expensive to create doesn't a PRNG need to be a single reusable instance like you suggested in order to work properly?
    – bruglesco
    Apr 17 at 22:09










  • @bruglesco The new random allows you to create multiple random number generators and they should work independently (and I hear well). But in my personal opinion: One should be enough for an app.
    – Martin York
    Apr 17 at 23:06










  • Doesn’t non-member begin and end need to be unqualified to really be universal? std::begin will work for a primitive array and std collections, but not for custom collections and ranges from 3rd party libraries that are not in the std namespace. You need to use ADL, just like with swap.
    – JDługosz
    Apr 18 at 6:30










  • Thanks a lot for reviewing in so much detail. Thanks for the useful comments. I will incorporate the suggested changes. I got to learn a lot. :-)
    – Rishi Agrawal
    Apr 18 at 7:24










  • @JDługosz I see what you are saying. Do be honest I had not thought about that, but its a good point. You are saying for types that don't have a begin/end method but do have specializations of the begin/end free standing methods. Personally I would hope that if you implement iterator like semantics for your object you also implement the begin/end method, but I can see how it is not required.
    – Martin York
    Apr 18 at 16:54















up vote
5
down vote



accepted










For such a simple case this Makefile is a waste.



It can be replaced with:



> rm Makefile
> export CXXFLAGS ="-std=c++17 -Wall -Werror"
> make lambdas


The standard implicit rules of Make will build lambdas from lambdas.cc



Sure Good use:



 std::generate(v.begin(), v.end(), [n = 0]() mutable n = n + 5; return n;);


Probably not a good example:



 std::for_each(v.begin(), v.end(),
(int n) std::cout << " " << n; );


I like (as it shows intent better).



 std::copy(v.begin(), v.end(),
std::ostream_iterator<int>(std::cout, "n");


But I think the modern (and idiomatic) form is:



 for(auto const& item: v) 
std::cout << v << "n";



I like this even less:



 std::for_each(v.begin(), v.end(), printInt);


You could have just as easily written:



 printVect(v);


Here the lambda is too large. At this size you should be creating a functor. If you have to do it inline then don't indent it all the way to the right like that. Some people don't have wide screens.



 std::for_each(v.begin(), v.end(), (int n) 
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);


OK. I'll ignore the rest of the for_each as I think we have covered the main points.



Good:



 std::sort(v.begin(), v.end());


Erase/Remove is a good example. Though this lambda is terrible.



 auto eraseBegin = std::remove_if(v.begin(), v.end(), (const int n) 
if (n%4 == 0)
return true;
else
return false;

);


Don't use a if statement to generate a true/false result. That value is an inherent part of the expression.



 if (n%4 == 0) 
return true;
else
return false;



Can be simplified to:



 return n%4 == 0;


Now that's a good lambda.



 auto eraseBegin = std::remove_if(v.begin(), v.end(),
(const int n) return n%4 == 0;);
v.erase(eraseBegin, v.end());


Good:



 eraseBegin = std::remove(v.begin(), v.end(), numberToRemove);
v.erase(eraseBegin, v.end());


Good:



 auto maxElementIt = std::max_element(v.begin(), v.end());
auto maxElement = *(maxElementIt);


Good:



 std::replace(v.begin(), v.end(), maxElement, -1);


I like this: it's a good simple example of random usage.



void shuffleVector(std::vector <int> &v) 
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);
std::cerr << "nnPrinting the shuffled vector.nn";
std::for_each(v.begin(), v.end(), printInt);



That random number generator is very expensive to create. And once you have it up and running, why recreate it each time? So I would make the random number stuff static inside the function:



void shuffleVector(std::vector <int> &v) {
static std::random_device rd;
static std::mt19937 g(rd());


As a side note:



The standard introduced std::begin() and std::end(). So you can now use these rather than the member versions. This allows you to generalize the code so it can be used on any container type (including arrays).



using std::begin;
using std::end;
std::for_each(begin(v), end(v), doStuff);


Now you don't need to care about the type of v. You can even change it to a C-Array and it would still work.






share|improve this answer























  • I apologize if I'm wrong but beyond being expensive to create doesn't a PRNG need to be a single reusable instance like you suggested in order to work properly?
    – bruglesco
    Apr 17 at 22:09










  • @bruglesco The new random allows you to create multiple random number generators and they should work independently (and I hear well). But in my personal opinion: One should be enough for an app.
    – Martin York
    Apr 17 at 23:06










  • Doesn’t non-member begin and end need to be unqualified to really be universal? std::begin will work for a primitive array and std collections, but not for custom collections and ranges from 3rd party libraries that are not in the std namespace. You need to use ADL, just like with swap.
    – JDługosz
    Apr 18 at 6:30










  • Thanks a lot for reviewing in so much detail. Thanks for the useful comments. I will incorporate the suggested changes. I got to learn a lot. :-)
    – Rishi Agrawal
    Apr 18 at 7:24










  • @JDługosz I see what you are saying. Do be honest I had not thought about that, but its a good point. You are saying for types that don't have a begin/end method but do have specializations of the begin/end free standing methods. Personally I would hope that if you implement iterator like semantics for your object you also implement the begin/end method, but I can see how it is not required.
    – Martin York
    Apr 18 at 16:54













up vote
5
down vote



accepted







up vote
5
down vote



accepted






For such a simple case this Makefile is a waste.



It can be replaced with:



> rm Makefile
> export CXXFLAGS ="-std=c++17 -Wall -Werror"
> make lambdas


The standard implicit rules of Make will build lambdas from lambdas.cc



Sure Good use:



 std::generate(v.begin(), v.end(), [n = 0]() mutable n = n + 5; return n;);


Probably not a good example:



 std::for_each(v.begin(), v.end(),
(int n) std::cout << " " << n; );


I like (as it shows intent better).



 std::copy(v.begin(), v.end(),
std::ostream_iterator<int>(std::cout, "n");


But I think the modern (and idiomatic) form is:



 for(auto const& item: v) 
std::cout << v << "n";



I like this even less:



 std::for_each(v.begin(), v.end(), printInt);


You could have just as easily written:



 printVect(v);


Here the lambda is too large. At this size you should be creating a functor. If you have to do it inline then don't indent it all the way to the right like that. Some people don't have wide screens.



 std::for_each(v.begin(), v.end(), (int n) 
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);


OK. I'll ignore the rest of the for_each as I think we have covered the main points.



Good:



 std::sort(v.begin(), v.end());


Erase/Remove is a good example. Though this lambda is terrible.



 auto eraseBegin = std::remove_if(v.begin(), v.end(), (const int n) 
if (n%4 == 0)
return true;
else
return false;

);


Don't use a if statement to generate a true/false result. That value is an inherent part of the expression.



 if (n%4 == 0) 
return true;
else
return false;



Can be simplified to:



 return n%4 == 0;


Now that's a good lambda.



 auto eraseBegin = std::remove_if(v.begin(), v.end(),
(const int n) return n%4 == 0;);
v.erase(eraseBegin, v.end());


Good:



 eraseBegin = std::remove(v.begin(), v.end(), numberToRemove);
v.erase(eraseBegin, v.end());


Good:



 auto maxElementIt = std::max_element(v.begin(), v.end());
auto maxElement = *(maxElementIt);


Good:



 std::replace(v.begin(), v.end(), maxElement, -1);


I like this: it's a good simple example of random usage.



void shuffleVector(std::vector <int> &v) 
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);
std::cerr << "nnPrinting the shuffled vector.nn";
std::for_each(v.begin(), v.end(), printInt);



That random number generator is very expensive to create. And once you have it up and running, why recreate it each time? So I would make the random number stuff static inside the function:



void shuffleVector(std::vector <int> &v) {
static std::random_device rd;
static std::mt19937 g(rd());


As a side note:



The standard introduced std::begin() and std::end(). So you can now use these rather than the member versions. This allows you to generalize the code so it can be used on any container type (including arrays).



using std::begin;
using std::end;
std::for_each(begin(v), end(v), doStuff);


Now you don't need to care about the type of v. You can even change it to a C-Array and it would still work.






share|improve this answer















For such a simple case this Makefile is a waste.



It can be replaced with:



> rm Makefile
> export CXXFLAGS ="-std=c++17 -Wall -Werror"
> make lambdas


The standard implicit rules of Make will build lambdas from lambdas.cc



Sure Good use:



 std::generate(v.begin(), v.end(), [n = 0]() mutable n = n + 5; return n;);


Probably not a good example:



 std::for_each(v.begin(), v.end(),
(int n) std::cout << " " << n; );


I like (as it shows intent better).



 std::copy(v.begin(), v.end(),
std::ostream_iterator<int>(std::cout, "n");


But I think the modern (and idiomatic) form is:



 for(auto const& item: v) 
std::cout << v << "n";



I like this even less:



 std::for_each(v.begin(), v.end(), printInt);


You could have just as easily written:



 printVect(v);


Here the lambda is too large. At this size you should be creating a functor. If you have to do it inline then don't indent it all the way to the right like that. Some people don't have wide screens.



 std::for_each(v.begin(), v.end(), (int n) 
std::cout << " CurrentVal(" << n << ")";
n = n + 1; // Changing the value.
std::cout << " ChangedVal(" << n << ")";
);


OK. I'll ignore the rest of the for_each as I think we have covered the main points.



Good:



 std::sort(v.begin(), v.end());


Erase/Remove is a good example. Though this lambda is terrible.



 auto eraseBegin = std::remove_if(v.begin(), v.end(), (const int n) 
if (n%4 == 0)
return true;
else
return false;

);


Don't use a if statement to generate a true/false result. That value is an inherent part of the expression.



 if (n%4 == 0) 
return true;
else
return false;



Can be simplified to:



 return n%4 == 0;


Now that's a good lambda.



 auto eraseBegin = std::remove_if(v.begin(), v.end(),
(const int n) return n%4 == 0;);
v.erase(eraseBegin, v.end());


Good:



 eraseBegin = std::remove(v.begin(), v.end(), numberToRemove);
v.erase(eraseBegin, v.end());


Good:



 auto maxElementIt = std::max_element(v.begin(), v.end());
auto maxElement = *(maxElementIt);


Good:



 std::replace(v.begin(), v.end(), maxElement, -1);


I like this: it's a good simple example of random usage.



void shuffleVector(std::vector <int> &v) 
std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);
std::cerr << "nnPrinting the shuffled vector.nn";
std::for_each(v.begin(), v.end(), printInt);



That random number generator is very expensive to create. And once you have it up and running, why recreate it each time? So I would make the random number stuff static inside the function:



void shuffleVector(std::vector <int> &v) {
static std::random_device rd;
static std::mt19937 g(rd());


As a side note:



The standard introduced std::begin() and std::end(). So you can now use these rather than the member versions. This allows you to generalize the code so it can be used on any container type (including arrays).



using std::begin;
using std::end;
std::for_each(begin(v), end(v), doStuff);


Now you don't need to care about the type of v. You can even change it to a C-Array and it would still work.







share|improve this answer















share|improve this answer



share|improve this answer








edited Apr 18 at 16:55


























answered Apr 17 at 15:44









Martin York

70.8k481244




70.8k481244











  • I apologize if I'm wrong but beyond being expensive to create doesn't a PRNG need to be a single reusable instance like you suggested in order to work properly?
    – bruglesco
    Apr 17 at 22:09










  • @bruglesco The new random allows you to create multiple random number generators and they should work independently (and I hear well). But in my personal opinion: One should be enough for an app.
    – Martin York
    Apr 17 at 23:06










  • Doesn’t non-member begin and end need to be unqualified to really be universal? std::begin will work for a primitive array and std collections, but not for custom collections and ranges from 3rd party libraries that are not in the std namespace. You need to use ADL, just like with swap.
    – JDługosz
    Apr 18 at 6:30










  • Thanks a lot for reviewing in so much detail. Thanks for the useful comments. I will incorporate the suggested changes. I got to learn a lot. :-)
    – Rishi Agrawal
    Apr 18 at 7:24










  • @JDługosz I see what you are saying. Do be honest I had not thought about that, but its a good point. You are saying for types that don't have a begin/end method but do have specializations of the begin/end free standing methods. Personally I would hope that if you implement iterator like semantics for your object you also implement the begin/end method, but I can see how it is not required.
    – Martin York
    Apr 18 at 16:54

















  • I apologize if I'm wrong but beyond being expensive to create doesn't a PRNG need to be a single reusable instance like you suggested in order to work properly?
    – bruglesco
    Apr 17 at 22:09










  • @bruglesco The new random allows you to create multiple random number generators and they should work independently (and I hear well). But in my personal opinion: One should be enough for an app.
    – Martin York
    Apr 17 at 23:06










  • Doesn’t non-member begin and end need to be unqualified to really be universal? std::begin will work for a primitive array and std collections, but not for custom collections and ranges from 3rd party libraries that are not in the std namespace. You need to use ADL, just like with swap.
    – JDługosz
    Apr 18 at 6:30










  • Thanks a lot for reviewing in so much detail. Thanks for the useful comments. I will incorporate the suggested changes. I got to learn a lot. :-)
    – Rishi Agrawal
    Apr 18 at 7:24










  • @JDługosz I see what you are saying. Do be honest I had not thought about that, but its a good point. You are saying for types that don't have a begin/end method but do have specializations of the begin/end free standing methods. Personally I would hope that if you implement iterator like semantics for your object you also implement the begin/end method, but I can see how it is not required.
    – Martin York
    Apr 18 at 16:54
















I apologize if I'm wrong but beyond being expensive to create doesn't a PRNG need to be a single reusable instance like you suggested in order to work properly?
– bruglesco
Apr 17 at 22:09




I apologize if I'm wrong but beyond being expensive to create doesn't a PRNG need to be a single reusable instance like you suggested in order to work properly?
– bruglesco
Apr 17 at 22:09












@bruglesco The new random allows you to create multiple random number generators and they should work independently (and I hear well). But in my personal opinion: One should be enough for an app.
– Martin York
Apr 17 at 23:06




@bruglesco The new random allows you to create multiple random number generators and they should work independently (and I hear well). But in my personal opinion: One should be enough for an app.
– Martin York
Apr 17 at 23:06












Doesn’t non-member begin and end need to be unqualified to really be universal? std::begin will work for a primitive array and std collections, but not for custom collections and ranges from 3rd party libraries that are not in the std namespace. You need to use ADL, just like with swap.
– JDługosz
Apr 18 at 6:30




Doesn’t non-member begin and end need to be unqualified to really be universal? std::begin will work for a primitive array and std collections, but not for custom collections and ranges from 3rd party libraries that are not in the std namespace. You need to use ADL, just like with swap.
– JDługosz
Apr 18 at 6:30












Thanks a lot for reviewing in so much detail. Thanks for the useful comments. I will incorporate the suggested changes. I got to learn a lot. :-)
– Rishi Agrawal
Apr 18 at 7:24




Thanks a lot for reviewing in so much detail. Thanks for the useful comments. I will incorporate the suggested changes. I got to learn a lot. :-)
– Rishi Agrawal
Apr 18 at 7:24












@JDługosz I see what you are saying. Do be honest I had not thought about that, but its a good point. You are saying for types that don't have a begin/end method but do have specializations of the begin/end free standing methods. Personally I would hope that if you implement iterator like semantics for your object you also implement the begin/end method, but I can see how it is not required.
– Martin York
Apr 18 at 16:54





@JDługosz I see what you are saying. Do be honest I had not thought about that, but its a good point. You are saying for types that don't have a begin/end method but do have specializations of the begin/end free standing methods. Personally I would hope that if you implement iterator like semantics for your object you also implement the begin/end method, but I can see how it is not required.
– Martin York
Apr 18 at 16:54













 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f192284%2fexamples-of-lambda-functions-stdfor-each-max-element-remove-if-etc%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation