mirror of
https://gitlab.com/fbb-git/cppannotations
synced 2024-11-18 10:06:54 +01:00
76 lines
3 KiB
Text
76 lines
3 KiB
Text
In bf(C++) pointers to (member) functions have fairly strict rvalues. They can
|
|
only point to functions matching their types. This becomes a problem when
|
|
defining templates where the type of a function pointer may depend on the
|
|
template's parameters.
|
|
|
|
To solve this problem the C++11 standard introduces
|
|
hi(polymorphous wrapper)
|
|
hi(function pointer: polymorphic)
|
|
em(polymorphous (function object) wrappers). Polymorphous wrappers refer
|
|
to function pointers, member functions or function objects, as long as their
|
|
parameters match in type and number.
|
|
|
|
Before using polymorphic function wrappers the header file `tthi(functional)'
|
|
must be included.
|
|
|
|
Polymorphic function wrappers are made available through the
|
|
tt(std::function)hi(function (std::)) class template. Its template argument
|
|
is the prototype of the function to create a wrapper for. Here is an example
|
|
of the definition of a polymorphic function wrapper that can be used to point
|
|
to a function expecting two tt(int) values and returning an tt(int):
|
|
verb(
|
|
std::function<int (int, int)> ptr2fun;
|
|
)
|
|
Here, the template's parameter is tt(int (int, int)), indicating a
|
|
function expecting two tt(int) arguments, and returning and tt(int). Other
|
|
prototypes return other, matching, function wrappers.
|
|
|
|
Such a function wrapper can now be used to point to any function the wrapper
|
|
was created for. E.g., `tt(plus<int> add)' creates a functor defining an
|
|
tt(int operator()(int, int)) function call member. As this qualifies as a
|
|
function having prototype tt(int (int, int)), our tt(ptr2fun) may point to
|
|
tt(add):
|
|
verb(
|
|
ptr2fun = add;
|
|
)
|
|
|
|
If tt(ptr2fun) does not yet point to a function (e.g., it is merely
|
|
defined) and an attempt is made to call a function through it a
|
|
hi(bad_function_call)`tt(std::bad_function_call)'
|
|
exception is thrown. Also, a polymorphic function wrapper that hasn't been
|
|
assigned to a function's address represents the value tt(false) in logical
|
|
expressions (as if it had been a pointer having value zero):
|
|
verb(
|
|
std::function<int(int)> ptr2int;
|
|
|
|
if (not ptr2int)
|
|
cout << "ptr2int is not yet pointing to a function\n";
|
|
)
|
|
|
|
Polymorphous function wrappers can also be used to refer to functions,
|
|
functors or other polymorphous function wrappers having prototypes for which
|
|
standard conversions exist for either parameters or return values. E.g.,
|
|
verb(
|
|
bool predicate(long long value);
|
|
|
|
void demo()
|
|
{
|
|
std::function<int(int)> ptr2int;
|
|
|
|
ptr2int = predicate; // OK, convertible param. and return type
|
|
|
|
struct Local
|
|
{
|
|
short operator()(char ch);
|
|
};
|
|
|
|
Local object;
|
|
|
|
std::function<short(char)> ptr2char(object);
|
|
|
|
ptr2int = object; // OK, object is a functor whose function
|
|
// operator has a convertible param. and
|
|
// return type.
|
|
ptr2int = ptr2char; // OK, now using a polym. funct. wrapper
|
|
}
|
|
)
|