Binding and Function Composition

How can std::bind be used for function composition?

std::bind can be used for function composition, which is the process of combining multiple functions to create a new function. By binding the result of one function as an argument to another function, you can create a composite function that performs a sequence of operations.

Consider the following example:

#include <functional>
#include <iostream>

int Multiply(int a, int b) { return a * b; }

int Add(int a, int b) { return a + b; }

int main() {
  auto MultiplyBy2 = std::bind(
    Multiply, 2, std::placeholders::_1);

  auto AddMultiplyBy2 = std::bind(
    Add, std::placeholders::_1,
    std::bind(MultiplyBy2, std::placeholders::_1)
  );

  // 5 + (5 * 2)
  std::cout << AddMultiplyBy2(5) << '\n';

  // 10 + (10 * 2)
  std::cout << AddMultiplyBy2(10) << '\n';
}
15
30

In this example, we have two simple functions: Multiply and Add, which perform multiplication and addition, respectively.

We first create a functor MultiplyBy2 by binding the first argument of Multiply to 2. This functor multiplies its argument by 2.

Next, we create another functor AddMultiplyBy2 by binding the second argument of Add to the result of calling MultiplyBy2 with the same argument as the first argument of Add.

The resulting AddMultiplyBy2 functor takes a single argument, multiplies it by 2 using MultiplyBy2, and then adds the result to the original argument.

When we call AddMultiplyBy2(5), it effectively computes 5 + (5 * 2), which equals 15. Similarly, AddMultiplyBy2(10) computes 10 + (10 * 2), which equals 30.

Function composition using std::bind allows you to create new functions by combining existing functions in a declarative way. It can be particularly useful when working with higher-order functions and creating reusable function components.

Here's another example that demonstrates function composition with multiple bound functions:

#include <cmath>
#include <functional>
#include <iostream>

int main() {
  auto Square = std::bind(
    std::multiplies<int>(),
    std::placeholders::_1,
    std::placeholders::_1
  );

  auto SquareRoot = std::bind(
    static_cast<double (*)(double)>(std::sqrt),
    std::placeholders::_1
  );

  auto SquareRootOfSquare = std::bind(
    SquareRoot,
    std::bind(Square, std::placeholders::_1));

  // sqrt(5 * 5)
  std::cout << SquareRootOfSquare(5) << '\n';

  // sqrt(10 * 10)
  std::cout << SquareRootOfSquare(10) << '\n';
}
5
10

In this example, we create two functors: Square and SquareRoot. Square multiplies its argument by itself using std::multiplies, while SquareRoot computes the square root of its argument using std::sqrt.

We then compose these functors to create a new functor SquareRootOfSquare, which takes a single argument, squares it using Square, and then computes the square root of the result using SquareRoot.

When we call SquareRootOfSquare(5), it effectively computes the square root of 5 squared, which equals 5. Similarly, SquareRootOfSquare(10) computes the square root of 10 squared, which equals 10.

Function composition using std::bind allows you to create complex operations by combining simpler functions, promoting code reuse and expressiveness.

Function Binding and Partial Application

This lesson covers function binding and partial application using std::bind(), std::bind_front(), std::bind_back() and std::placeholders.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Binding Member Variables
Can std::bind be used to bind member variables in addition to member functions?
Binding and Const Member Functions
How does std::bind handle const member functions?
Binding and Function Templates
Can std::bind be used with function templates?
Binding and Lambda Expressions
Can std::bind be used with lambda expressions?
Binding and std::ref / std::cref
How can std::ref and std::cref be used with std::bind?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant