Function Objects in C++
(Heavily from https://cplusplus.com/reference/functional/)
Function objects are objects that work as functions. On an implementation level, however, function objects are objects of a class that implement operator()
, with zero to any number of arguments. Although functions and function-pointers can also be classified as function objects, it is the capability of an object of a class that implements operator() to carry state (that is, values in member attributes of the class) that makes it so useful.
Function objects that return a boolean type (predicates) naturally are used in algorithms that need decision-making.
They are typically used as arguments to functions, such as predicates or comparison functions passed to standard algorithms.
Header <functional>
This header defines some functions, wrapper classes and namespace placeholders
.
Functions
These functions create objects of wrapper classes based on its arguments:
bind
- Bind function arguments
cref
- Construct reference_wrapper to const
mem_fn
- Convert member function to function object
not1
- Return negation of unary function object
not2
- Return negation of binary function object
ref
- Construct reference_wrapper
Classes*
Wrapper classes
Wrapper classes are classes that hold an object and have an interface similar to that object, but adding or changing some of its features:
binary_negate
- Negate binary function object class
function
- Function wrapper
reference_wrapper
- Reference wrapper
unary_negate
- Negate unary function object class
Operator classes
Operator classes are classes that define functional objects that call operators:
bit_and
- Bitwise AND function object class
bit_or
- Bitwise OR function object class
bit_xor
- Bitwise XOR function object class
divides
- Division function object class
equal_to
- Function object class for equality comparison
greater
- Function object class for greater-than inequality comparison
greater_equal
- Function object class for greater-than-or-equal-to comparison
less
- Function object class for less-than inequality comparison
less_equal
- Function object class for less-than-or-equal-to comparison
logical_and
- Logical AND function object class
logical_not
- Logical NOT function object class
logical_or
- Logical OR function object class
minus
- Subtraction function object class
modulus
- Modulus function object class
multiplies
- Multiplication function object class
negate
- Negative function object class
not_equal_to
- Function object class for non-equality comparison
plus
- Addition function object class
Other classes
bad_function_call
- Exception thrown on bad call (class)
hash
- Default hash function object class
is_bind_expression
- Is bind expression
is_placeholder
- Is placeholder
Namespace placeholders
Function std::bind
in Depth (<functional>
)
Prototypes:
template <class Fn, class... Args> bind (Fn&& fn, Args&&... args); template <class Ret, class Fn, class... Args> bind (Fn&& fn, Args&&... args);
bind()
returns a function object based on fn, but with its arguments bound to args. Each argument may either be bound to a value or be a placeholder:
- If bound to a value, calling the returned function object will always use that value as argument.
- If a placeholder, calling the returned function object forwards an argument passed to the call (the one whose order number is specified by the placeholder).
Calling the returned object returns the same type as fn, unless a specific return type is specified as Ret (second prototype). (Note that Ret is the only template parameter that cannot be implicitly deduced by the arguments passed to this function).
The type of the returned object has the following properties:
- Its functional call returns the same as fn with its arguments bound to args... (or forwarded, for placeholders).
- For the first prototype, it may have a member
result_type
: if Fn is a pointer to function or member function type, it is defined as an alias of its return type. Otherwise, it is defined asFn::result_type
, if there should be such a member type.
>An example:
[...]
// bind example #include <iostream> // std::cout #include <functional> // std::bind // a function: (also works with function object: std::divides<double> my_divide;) double my_divide (double x, double y) {return x/y;} struct MyPair { double a,b; double multiply() {return a*b;} }; int main () { using namespace std::placeholders; // adds visibility of _1, _2, _3,... // binding functions: auto fn_five = std::bind (my_divide,10,2); // returns 10/2 std::cout << fn_five() << '\n'; // 5 auto fn_half = std::bind (my_divide,_1,2); // returns x/2 std::cout << fn_half(10) << '\n'; // 5 auto fn_invert = std::bind (my_divide,_2,_1); // returns y/x std::cout << fn_invert(10,2) << '\n'; // 0.2 auto fn_rounding = std::bind<int> (my_divide,_1,_2); // returns int(x/y) std::cout << fn_rounding(10,3) << '\n'; // 3 MyPair ten_two {10,2}; // binding members: auto bound_member_fn = std::bind (&MyPair::multiply,_1); // returns x.multiply() std::cout << bound_member_fn(ten_two) << '\n'; // 20 auto bound_member_data = std::bind (&MyPair::a,ten_two); // returns ten_two.a std::cout << bound_member_data() << '\n'; // 10 return 0; }
[...]
Functions std::ref
and std::cref
in Depth (<functional>
)
...
Prototypes:
template <class T> reference_wrapper<T> ref (T& elem) noexcept; template <class T> reference_wrapper<T> ref (reference_wrapper<T>& x) noexcept; template <class T> void ref (const T&&) = delete; template <class T> reference_wrapper<const T> cref (const T& elem) noexcept; template <class T> reference_wrapper<const T> cref (reference_wrapper<T>& x) noexcept; template <class T> void cref (const T&&) = delete;
These functions return a reference_wrapper
object of the appropriate type to hold an element of type T
or const T
respectively.
An example:
// ref example #include <iostream> // std::cout #include <functional> // std::ref int main () { int foo (10); auto bar = std::ref(foo); ++bar; std::cout << foo << '\n'; return 0; }
(Note that should we have invoked std::cref
instead, the returned object, bar, would not be incrementable, but the source object, foo, would.)
Function std::mem_fn
(<functional>
)
template <class Ret, class T> /* unspecified */ mem_fn (Ret T::* pm);
std::mem_fn
converts member function pm to a function object. It returns a function object whose functional call invokes the member function pointed by pm.
The type of the returned object has the following properties:
- Its functional call takes as first argument an object of type T (or a reference or a pointer to it) and, as additional arguments, the arguments taken by pm (if any). The effect of such a call with fn as first argument are the same as calling
fn
.*pm (or(*fn).*pm
if fn is a pointer), forwarding any additional arguments. - It has a member
result_type
, defined as an alias of Ret (which is the return type of pm). - If the member pointed by pm takes no arguments, it has a member argument_type, defined as an alias of
T*
. - If the member pointed by pm takes one argument, it has a member
first_argument_type
, defined as an alias ofT*
, and a membersecond_argument_type
, defined as an alias of the argument taken by pm. - It is nothrow move-constructible, nothrow copy-constructible and nothrow copy-assignable.
An example:
// mem_fn example #include <iostream> // std::cout #include <functional> // std::mem_fn struct int_holder { int value; int triple() {return value*3;} }; int main () { int_holder five {5}; // call member directly: std::cout << five.triple() << '\n'; // 15 // same as above using a mem_fn: auto triple = std::mem_fn (&int_holder::triple); std::cout << triple(five) << '\n'; // 15 return 0; }
[...]