Search code examples
c++bind2nd

Explain the code?


I came across this code. From the output I could infer that remainder array stores the remainder of numbers array when divided by 2. But the syntax is unfamiliar to me.

#include <iostream>
#include <functional>
#include <algorithm>

using namespace std;

int main ( )
{

    int numbers[ ] = {1, 2, 3};

    int remainders[3];

    transform ( numbers, numbers + 3, remainders, bind2nd(modulus<int>( ), 2) );

    for (int i = 0; i < 3; i++)
    {
        cout << (remainders[i] == 1 ? "odd" : "even") << "\n";
    }
    return 0;

}

What do transform and bind2nd do in this context? I read the documentation but it was not clear to me.


Solution

  • std::bind2nd is an old function for binding a value to the second parameter of a function. It has been replaced by std::bind and lambdas.

    std::bind2nd returns a callable object that takes one parameter and calls the wrapped callable with that parameter as its first parameter and the bound parameter as its second parameter:

    int foo(int a, int b)
    {
        std::cout << a << ' ' << b;
    }
    
    int main()
    {
        auto bound = std::bind2nd(foo, 42);
        bound(10); // prints "10 42"
    }
    

    std::bind2nd (and its partner std::bind1st) were deprecated in C++11 and removed in C++17. They were replaced in C++11 by the more flexible std::bind as well as lambda expressions:

    int foo(int a, int b)
    {
        std::cout << a << ' ' << b;
    }
    
    int main()
    {
        auto bound = std::bind(foo, std::placeholders::_1, 42);
        bound(10); // prints "10 42", just like the std::bind2nd example above
    
        auto lambda = [](int a) { foo(a, 42); };
        lambda(10); // prints "10 42", same as the other examples
    }
    

    std::transform calls a callable on each element of a range and stores the result of the call into the output range.

    int doubleIt(int i)
    {
        return i * 2;
    }
    
    int main()
    {
        int numbers[] = { 1, 2, 3 };
        int doubled[3];
    
        std::transform(numbers, numbers + 3, doubled, doubleIt);
        // doubled now contains { 2, 4, 6 }
    }