Skip to content

techtrendings.com

Let's explore

Menu
Menu

Bind and placeholders in C++

Posted on January 3, 2022January 12, 2022 by Avidlearner

Bind() introduced in c++11 allows you to bind parameters of a callable in a flexible way. You
can bind parameters to fixed values, and you can even rearrange parameters in a different order.

bind(function pointer, bound arguments)

For example, let add3 be a function that takes 3 integer arguments and returns an int that is the sum of its arguments: int add3(int a, int b, int c)

{

int sum = a+b+c;

cout << a << ‘+’ << b << ‘+’ << c << ‘=’ << sum << endl;

return sum;

}

Let int1, int2, and int3 be three int variables. Then bind(add3, int1, int2, int3) creates and returns a function object whose function call operator takes no arguments and calls add3 with the values in the three integer variables and returns an int.

Now, We can invoke the function call operator like below:

int result = bind(add3, int1, int2, int3)();

The final effect is as if add3 was called as:

int result = add3(int1, int2, int3);

When the function object is created, a pointer to the function is stored in a member variable(here it is add3), and the values in the bound arguments are copied into the function object and stored as member variable values. When the function call operator is executed, the saved pointer is used to call the function, and the saved values are supplied as arguments to that function.

Bind with placeholders

when we use the function object in a call, the final function arguments can be taken from a mixture of bound arguments and the arguments supplied in the call, which will be termed as the call arguments. This is done with special placeholders in the list of bound arguments.

Suppose you have a function called fun() accepting two arguments:
void fun(int num, std::string str)
{
cout << “fun(” << num << “, ” << str << “)” << endl;
}
The following code demonstrates how you can use bind() to bind the second argument of fun()
to a fixed value, str. The result is stored in func1().

The auto keyword is used because the return type of bind() is unspecified.

Arguments that are not bound to specific values should be specified as _1, _2, _3, and so on.

These are defined in the std::placeholders namespace. In the definition of func1(), the _1 specifies

where the first argument to func1() needs to go when fun() is called.

After this, func1() can be called with just a single integer argument.
std::string str = “abc”;
auto func1 = bind(fun, placeholders::_1, str);
func1(16);


Here is the output:
fun(16, abc)


bind can also be used to rearrange the arguments, as shown in the following code.

The _2 specifies where the second argument to func2() needs to go when fun() is called.

In other words, the func2() binding means that the first argument to func2() will become the

second argument to fun(), and the second argument to func2() will become the first

argument to fun().

auto func2 = bind(fun, placeholders::_2, placeholders::_1);
func2(“Test”, 2);


The output is as follows:
fun(2, Test)

Suppose you have function as follows:

void increment(int& val){ ++val; }

Now, if you call this function as follows, then value of index will be incremented to 1

int index = 0;

increment(index);

If you use bind() to call it as follows then the value of index is not incremented because a copy
of index is made, and a reference to this copy is bound to the first parameter of the increment()
function:
int index = 0;
auto incr = bind(increment, index);
incr();


Using std::ref() to pass a proper reference correctly increments index:
int index = 0;
auto incr = bind(increment, ref(index));
incr();

Issue with Binding

Suppose you have following two overloaded functions. One accepts an integer and the other

accepts a floating-point number:


void overloaded(int num) {}
void overloaded(float f) {}

If you want to use bind() with these overloaded functions, you need to explicitly specify which

of the two overloads you want to bind. The following will not compile:
auto func3 = bind(overloaded, placeholders::_1); // ERROR

If you want to bind the parameters of the overloaded function accepting a floating-point

argument, you need the following syntax:
auto func4 = bind((void(*)(float))overloaded, placeholders::_1); // OK

Binding with Algorithm

Consider find_if() algorithm to find the first element in a sequence that is greater than or equal

to 100. The following code uses bind() to bind the second parameter of greater_equal to a fixed

value of 100:

// Code for inputting scores into the vector omitted, similar as earlier.
vector<int> myVector {1,2,3,5,6}

auto endIter = end(myVector);
auto it = find_if(begin(myVector), endIter,
bind(greater_equal<>(), placeholders::_1, 100));
if (it == endIter) {
cout << “No perfect scores” << endl;
} else {
cout << “Found a \”perfect\” score of ” << *it << endl;
}

Hope you found this article useful.

Related

Leave a Reply Cancel reply

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

Recent Posts

  • Implement Trie Data Structure in C++- LeetCode
  • How TLS Works
  • C++ – Factory Design Pattern – Creation Design Pattern
  • C++ – Strategy Design Pattern – Behavioral Design Pattern
  • LFU Cache Implementation – LeetCode

Recent Comments

  • automatically like friends photos on instagram on Program to find unpaired element in an Array in C++|Leetcode |techtrendings
  • Twicsy on Program to find unpaired element in an Array in C++|Leetcode |techtrendings

Archives

  • January 2023
  • November 2022
  • August 2022
  • June 2022
  • May 2022
  • March 2022
  • February 2022
  • January 2022

Categories

  • Algorithm
  • Algorithm
  • C++
  • Design Patterns
  • Multithreading
  • OS Concepts
  • Programming
  • Uncategorized

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Join Our Mailing List for the Latest News and Updates.

© 2023 techtrendings.com | Powered by Superbs Personal Blog theme