std::bind and Its Alternatives

Lesson Introduction

Welcome! In modern C++ development, crafting flexible and reusable code is key to building highly maintainable applications. One powerful tool to aid in this endeavor is std::bind, which allows you to create function objects by binding specific arguments to functions. By the end of this lesson, you will understand std::bind, learn its syntax, explore its usage, and become familiar with lambda expressions as an alternative.

Introduction to std::bind

std::bind is part of the <functional> library in C++. It allows you to bind one or more arguments to a function, creating new callable objects. Callable objects are entities that can be called as if they are functions, including normal functions, function objects, and lambda expressions. Binding defines the values for the arguments, but it doesn’t invoke the function. The function is invoked only when someone calls the function object returned by std::bind. We have created such functions manually in the previous lesson to practice; std::bind can help you achieve the same result faster and easier!

Example Using std::bind

Here's an example to understand std::bind:

#include <iostream>
#include <functional>

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

int main() {
    // Using std::bind to create a new function that always adds 5
    auto add_five = std::bind(add, std::placeholders::_1, 5);
    std::cout << "3 + 5 = " << add_five(3) << '\n'; // Output: 3 + 5 = 8

    return 0;
}

In this example:

  • add is a function that takes two ints and returns their sum.
  • std::bind creates add_five by binding the second argument of add to 5.
  • Calling add_five(3) results in add(3, 5), producing 8.

Placeholders are special objects used in std::bind to represent arguments provided later. By using a placeholder, we say: "Hey, there will be an argument, but it is not present right now!"

In this example, std::placeholders::_1 means that the first parameter to add_five will become the first parameter to add.

If you had a need for additional parameters, you could use std::placeholders::_2 for the second parameter, std::placeholders::_3 for the third, and so on.

Binding by reference

Binding by reference can be useful when you need the bound parameter to reflect any changes made to the original variable. This means that the bound function will use the current value of the variable when invoked, not the value it had when the function was created.

To bind by reference, use std::ref for non-const references and std::cref for const references:

#include <iostream>
#include <functional>

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

int main() {
    int x = 5;
    auto add_ref = std::bind(add, std::ref(x), std::placeholders::_1);
    std::cout << "5 + 3 = " << add_ref(3) << '\n'; // Output: 5 + 3 = 8

    x = 10;
    std::cout << "10 + 2 = " << add_ref(2) << '\n'; // Output: 10 + 2 = 12

    const int y = 10;
    auto add_const_ref = std::bind(add, std::cref(y), std::placeholders::_1);
    std::cout << "10 + 2 = " << add_const_ref(2) << '\n'; // Output: 10 + 2 = 12

    return 0;
}

In this example:

  • std::ref(x) binds x by reference which means x retains its original memory address. Therefore, changes to x will be reflected in the bound function. Initially, x is 5, so add_ref(3) results in add(5, 3). When x is changed to 10, add_ref(2) results in add(10, 2).

  • std::cref(y) binds y by const reference. This means the bound function can only read, not modify, y. The example binds y, which is 10, and add_const_ref(2) results in add(10, 2). Note that attempts to modify y would result in compilation errors due to its const qualification.

Binding by reference is particularly useful for working with large data structures where copying them would be inefficient.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal