std::for_each Tutorial : Usage Details with Examples

The std::for_each() algorithm allows us to iterate over a given range of elements and perform operations over them.

When to use std::for_each() ?

Whenever you are iterating over the elements in a array or in a container and performing some different opeartions over them like accessing, modifying etc. Although you can achieve the same by typing complete for loop but it save you time and number of lines of code, also it reduces the chance of some bugs.

Signature of std::for_each algorithm

UnaryFunction for_each( InputIterator first, InputIterator last, UnaryFunction func );

Here func can be a global function, lambda function or function object. All elements from first to last will be derefrenced and applied to this “func()”.
In the end it returns the copy of “func()” i.e. the passed Unary function.

[showads ad=inside_post]

Lets see some examples,

Lets first create a std::vector of names (std::string)

void addNames( std::vector<std::string> & vecNames)
{
    vecNames.push_back("Varun");
    vecNames.push_back("Ajay");
    vecNames.push_back("John");
    vecNames.push_back("Rita");
}

Now, Display Each name in std::vector using std::for_each and global function,

void printName(std::string name)
{
    std::cout<<name<<std::endl;
}

void example_1(std::vector<std::string> & vecNames)
{
    // Display Each name in vector using std::for_each and global function
    std::for_each(vecNames.begin(), vecNames.end(), printName);
}

Let’s Display Each name in std::vector using std::for_each and lambda function,

void example_2(std::vector<std::string> & vecNames)
{
    // Now Display Each name in vector using std::for_each and Lambda function
    std::for_each(vecNames.begin(), vecNames.end(), [](std::string name)
                            {
                                std::cout<<name<<std::endl;
                            });
}

Now, suppose we have to count the number of names and in the end print the biggest name from the given std::vector of names.
Let’s do this using std::for_each and a function object.

First Create a function object that will keep the track of largest name and total number of names traversed.

class NameChecker
{
    std::string m_biggerName;
    int m_nameCount;
public:
    NameChecker(): m_biggerName(""), m_nameCount(0)
    {}
    void operator()(std::string name)
    {
        if(m_biggerName.size() < name.size())
            m_biggerName = name;
        m_nameCount++;
    }

    const std::string& getBiggerName() const {
        return m_biggerName;
    }

    int getNameCount() const {
        return m_nameCount;
    }
};

Now lets use the NameChecker function object to acheive the result,

void example_3(std::vector<std::string> & vecNames)
{
    // Now count the number of names and in end print the biggest name
    // Let's do this with std::for_each and a function object.

    NameChecker nameCheckerObj = std::for_each(vecNames.begin(), vecNames.end(), NameChecker());

    std::cout<<std::endl<<"Biggest Name = "<<nameCheckerObj.getBiggerName()<<std::endl;
    std::cout<<std::endl<<"Total Names = "<<nameCheckerObj.getNameCount()<<std::endl;

}

As, std::for_each returns the copy of passed Unary Function, so we have used that to keep track of the elements.

Complete Working example is as follows,

[code language=”cpp” collapse=”true”]

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

void addNames( std::vector<std::string> & vecNames)
{
    vecNames.push_back("Varun");
    vecNames.push_back("Ajay");
    vecNames.push_back("John");
    vecNames.push_back("Rita");
}
void printName(std::string name)
{
    std::cout<<name<<std::endl;
}

class NameChecker
{
    std::string m_biggerName;
    int m_nameCount;
public:
    NameChecker(): m_biggerName(""), m_nameCount(0)
    {}
    void operator()(std::string name)
    {
        if(m_biggerName.size() < name.size())
            m_biggerName = name;
        m_nameCount++;
    }

    const std::string& getBiggerName() const {
        return m_biggerName;
    }

    int getNameCount() const {
        return m_nameCount;
    }
};

void example_1(std::vector<std::string> & vecNames)
{
    // Display Each name in vector using std::for_each and global function
    std::for_each(vecNames.begin(), vecNames.end(), printName);
}

void example_2(std::vector<std::string> & vecNames)
{
    // Now Display Each name in vector using std::for_each and Lambda function
        std::for_each(vecNames.begin(), vecNames.end(), [](std::string name)
                                                        {
                                                            std::cout<<name<<std::endl;
                                                        });
}
void example_3(std::vector<std::string> & vecNames)
{
    // Now count the number of names and in end print the biggest name
    // Let’s do this with std::for_each and a function object.

    NameChecker nameCheckerObj = std::for_each(vecNames.begin(), vecNames.end(), NameChecker());

    std::cout<<std::endl<<"Biggest Name = "<<nameCheckerObj.getBiggerName()<<std::endl;
    std::cout<<std::endl<<"Total Names = "<<nameCheckerObj.getNameCount()<<std::endl;

}
int main()
{
    std::vector<std::string> vecNames;
    addNames(vecNames);

    example_1(vecNames);
    example_2(vecNames);
    example_3(vecNames);

    return 0;

}

[/code]

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top