...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
An n-ary Polymorphic Function Object adapter template for an unary Polymorphic Function Object target function. When called, its arguments are bundled to a Random Access Sequence that is passed to the target function object.
The call operators of resulting function objects are strictly typed (in other words, non-templatized) with the types from a Sequence.
The type of the target function is allowed to be const qualified or a reference.
Const qualification is preserved and propagated appropriately (in other
words, only const versions of operator()
can be used
if the target function object is const - or, in case the target function
object is held by value, the adapter is const).
Note | |
---|---|
For Microsoft Visual C++ 7.1 (Visual Studio 2003) the detection of the Function Object's const qualification easily causes an internal error. Therefore the adapter is always treated as if it was const. |
Tip | |
---|---|
If the type sequence passed to this template contains non-reference elements, the element is copied only once - the call operator's signature is optimized automatically to avoid by-value parameters. |
#include <boost/fusion/functional/adapter/unfused_typed.hpp>
template <class Function, class Sequence> class unfused_typed;
Parameter |
Description |
Default |
---|---|---|
|
A unary Polymorphic Function Object |
|
|
A Sequence |
Notation
F
A possibly const qualified, unary Polymorphic Function Object type or reference type thereof
f
An object convertible to F
S
A Sequence of parameter types
UT
The type unfused_typed<F,S>
ut
An instance of UT
,
initialized with f
a0
...aN
Arguments to ut
,
convertible to the types in S
Expression |
Semantics |
---|---|
|
Creates a fused function as described above, initializes the
target function with |
|
Creates a fused function as described above, attempts to use
|
|
Calls |
struct add_assign // applies operator+= { typedef void result_type; // for simplicity template <typename T> void operator()(T & lhs, T const & rhs) const { lhs += rhs; } }; template <class Tie> class fused_parallel_adder { Tie tie_dest; public: explicit fused_parallel_adder(Tie const & dest) : tie_dest(dest) { } typedef void result_type; template <class Seq> void operator()(Seq const & s) const { for_each( zip(tie_dest,s), fused<add_assign>() ); } }; // accepts a tie and creates a typed function object from it struct fused_parallel_adder_maker { template <typename Sig> struct result; template <class Self, class Seq> struct result< Self(Seq) > { typedef typename remove_reference<Seq>::type seq; typedef unfused_typed< fused_parallel_adder<seq>, typename mpl::transform<seq, remove_reference<_> >::type > type; }; template <class Seq> typename result< void(Seq) >::type operator()(Seq const & tie) { return typename result< void(Seq) >::type( fused_parallel_adder<Seq>(tie) ); } }; unfused<fused_parallel_adder_maker> parallel_add; void try_it() { int a = 2; char b = 'X'; // the second call is strictly typed with the types deduced from the // first call parallel_add(a,b)(3,2); parallel_add(a,b)(3); parallel_add(a,b)(); assert(a == 8 && b == 'Z'); }