Section 6.2.  Algorithms in the MPL
Team LiB
Previous Section Next Section

6.2. Algorithms in the MPL

Like the STL algorithms, the MPL algorithms capture useful sequence operations and can be used as primitive building blocks for more complex abstractions. In the MPL algorithm set, you'll find just about everything you get from the standard <algorithm> header, similarly named.

That said, there are a few notable differences between the STL and MPL algorithms. You already know that metadata is immutable and therefore MPL algorithms must return new sequences rather than changing them in place, and that MPL algorithms operate directly on sequences rather than on iterator ranges. Aside from the fact that the choice to operate on sequences gives us a higher-level interface, it is also strongly related to the functional nature of template metaprogramming. When result sequences must be returned, it becomes natural to pass the result of one operation directly to another operation. For example:



    // Given a nonempty sequence Seq, returns the largest type in an


    // identical sequence where all instances of float have been


    // replaced by double.


    template <class Seq>


    struct biggest_float_as_double


      : mpl::deref<


            typename mpl::max_element<


               typename mpl::replace<


                   Seq


                 , float


                 , double


               >::type


             , mpl::less<mpl::sizeof_<_1>, mpl::sizeof_<_2> >


           >::type


      >


   {};



If max_element and replace operated on iterators instead of sequences, though, biggest_float_as_double would probably look something like this:



    template <class Seq>


    struct biggest_float_as_double


    {


        typedef typename mpl::replace<


          , typename mpl::begin<Seq>::type


          , typename mpl::end<Seq>::type


          , float


          , double


        >::type replaced;





        typedef typename mpl::max_element<


          , typename mpl::begin<replaced>::type


          , typename mpl::end<replaced>::type


          , mpl::less<mpl::sizeof_<_1>, mpl::sizeof_<_2> >


        >::type max_pos;





        typedef typename mpl::deref<max_pos>::type type;


    };



The upshot of operating primarily on whole sequences is an increase in interoperability, because the results of one algorithm can be passed smoothly to the next.

    Team LiB
    Previous Section Next Section