cppannotations/annotations/yo/functiontemplates/polymorphouswrappers.yo

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
}
)