Table of contents
std::bind
std::bind
Is a function template, defined in <functional>
the header file. Its function is to bind a callable object (such as a function, function pointer, member function, member function pointer, etc.) and several parameters to a new function object to form a new callable object.
std::bind
The function signature is as follows:
template< class F, class... Args >
constexpr /*unspecified*/ bind( F&& f, Args&&... args );
Among them, F
represents the callable object type to be bound, and Args
represents the parameter type to be bound. std::bind
Returns a new function object that can be called. When called, the bound callable object will be executed and the bound parameters will be passed to it.
Here is an example that demonstrates how to use std::bind
functions to bind a normal function to a new function object:
#include <iostream>
#include <functional>
int add(int a, int b) {
return a + b;
}
int main() {
auto add_five = std::bind(add, 5, std::placeholders::_1);
std::cout << add_five(3) << std::endl; // 输出 8
return 0;
}
In this example, we use std::bind
function to add
bind the function to a new function object add_five
and bind 5 to add
the first parameter of the function and _1
the placeholder to add
the second parameter of the function. Then, when calling add_five(3)
, we pass 3 as _1
the placeholder value, and add_five
the function object calls add(5, 3)
the function and returns the result 8.
When using std::bind
functions, you can use placeholders to specify which parameters need to be passed when calling the function object and which parameters need to be passed when binding. Commonly used placeholders are:
_1
: Indicates the first parameter when calling the function object._2
: Indicates the second parameter when calling the function object._3
: Indicates the third parameter when calling the function object.- ...
For example, if we want to pass the first and third parameters when calling the function object, and the second parameter when binding, we can use placeholders like this:
auto foo = std::bind(func, std::placeholders::_1, arg2, std::placeholders::_3);
When binding parameters, you can also use std::ref
a function to wrap a variable into a reference so that it can be passed by reference when calling the function object. For example:
int x = 42;
auto foo = std::bind(func, std::ref(x), std::placeholders::_1);
Here, we x
wrap the variable into a reference and bind it to func
the function along with the placeholder. When calling foo
a function object, the first argument will be x
a reference to .
In addition to std::bind
functions, C++11 also provides a new language feature - Lambda expressions, which can be used to replace std::bind
functions. Lambda expressions can more flexibly implement function object binding and parameter passing. For example:
auto add_five = [](int x) { return add(5, x); };
std::cout << add_five(3) << std::endl; // 输出 8
In this example, we use a Lambda expression to add(5, x)
bind the function to a new function object add_five
and pass 3 as an argument to it. add_five
The function object calls add(5, 3)
the function and returns the result 8.
std::function
Type was introduced in C++11 std::function
, which is a polymorphic function wrapper class that can be used to store and call any callable object, including function pointers, function objects, Lambda expressions, etc.
std::function
The function signature is as follows:
template <typename Signature>
class function;
Which Signature
represents the signature of the callable object, including the return value type and parameter list. For example, a return int
type, int
the signature of a function that accepts two type parameters is int(int, int)
.
std::function
operator()
A type can bind a callable object through a constructor or assignment operator, and can use operators to execute it when the object needs to be called .
Here is an example that demonstrates how to use std::function
types to store and call a Lambda expression:
#include <iostream>
#include <functional>
int main() {
std::function<int(int, int)> add = [](int x, int y) { return x + y; };
std::cout << add(3, 4) << std::endl; // 输出 7
return 0;
}
In this example, we define an std::function<int(int, int)>
object of type add
and use a Lambda expression to bind it to a function that returns the sum of two arguments. Then, when calling add(3, 4)
, we pass 3 and 4 as parameters and execute [](int x, int y) { return x + y; }
the Lambda expression, returning 7 as a result.
std::function
The type also supports comparison between empty function objects and function objects. You can use operator bool()
operators to determine whether the object is empty, and use operator==
the AND operator!=
operator to compare whether two function objects are equal.
Here is an example that demonstrates how to use std::function
types for comparison of function objects:
#include <iostream>
#include <functional>
int main() {
std::function<void()> func1 = []() { std::cout << "Hello, world!" << std::endl; };
std::function<void()> func2;
std::cout << std::boolalpha << (func1 == func2) << std::endl; // 输出 false
func2 = func1;
std::cout << std::boolalpha << (func1 == func2) << std::endl; // 输出 true
return 0;
}
In this example, we define two std::function<void()>
types of objects func1
and bind func2
them func1
to a Lambda expression. Then, when comparing the sums func1
for func2
equality, we use operator==
operators and output the comparison results. Since func2
it has not been bound to any callable object at this time, the sum func1
is func2
not equal and false is output. Next, we func2
bind to func1
the same callable object as , compare them again for equality, and output the comparison result. At this time, the sum is equal func1
and func2
true is output.
std::forward
std::forward
It is a function template in the C++11 standard library, used to forward parameters perfectly. Its main function is to forward the incoming parameters according to their value categories (lvalue or rvalue) in the function template to keep their value categories unchanged, thereby avoiding unnecessary copy and move operations.
std::forward
The function signature is as follows:
template <typename T>
constexpr T&& forward(typename std::remove_reference<T>::type& arg) noexcept;
template <typename T>
constexpr T&& forward(typename std::remove_reference<T>::type&& arg) noexcept;
Among them, the first template parameter T
indicates the type of parameter to be forwarded. If the parameter is an lvalue reference type, then T
it is the base type of this reference type. If the parameter is an rvalue reference type, then T
the base type of the rvalue reference type is added &&
.
std::forward
The function is to forward the incoming parameters arg
to another function (usually a template function) and maintain its original value category. During the forwarding process, if the parameter is an lvalue reference type, the forwarded type is also an lvalue reference type. If the parameter is an rvalue reference type, the forwarded type is also an rvalue reference type.
Here is an example that demonstrates how to use std::forward
for perfect forwarding:
cpp
Copy
#include <utility>
#include <iostream>
void foo(int& x) {
std::cout << "lvalue" << std::endl;
++x;
}
void foo(int&& x) {
std::cout << "rvalue" << std::endl;
++x;
}
template <typename T>
void bar(T&& x) {
std::forward<T>(x);
foo(std::forward<T>(x));
}
int main() {
int i = 42;
bar(i); // 输出 "lvalue"
std::cout << i; // 输出 43
bar(42); // 输出 "rvalue"
return 0;
}
In this example, we define two functions foo
that accept parameters of an lvalue reference type and an rvalue reference type respectively. Then, we define a template function bar
that accepts a parameter x
of type T&&
. In bar
the function, we use std::forward
perfect x
forward to foo
the function and keep its value category unchanged. When bar
the function is called, if the parameter passed in is an lvalue, the bar
function will call foo(int&)
the function and output "lvalue". In foo(int&)
the function, we increment the parameter by one and store the result back to the original parameter. So when we output i
the value, its value becomes 43. If the argument passed in is an rvalue, bar
the function will call foo(int&&)
the function and output "rvalue". In foo(int&&)
the function, we increment the argument by one, but since it is an rvalue, we cannot modify its value. Therefore, in this example, we only demonstrate std::forward
the use without actually modifying the value of the parameter.