Section 2.3.  Numerical Metafunctions
Team LiB
Previous Section Next Section

2.3. Numerical Metafunctions

You might find it astonishing that even metafunctions that yield numbers are invoked as shown above. No, we're not asking you to give the name type to something that is really a number. The result ::type of a metafunction with a numerical result really is a typea type known as an integral constant wrapper, whose nested ::value member is an integral constant. We'll explore the details of integral constant wrappers in Chapter 4, but in the meantime, the following example should give you a feeling for what we mean:



    struct five // integral constant wrapper for the value 5


    {


        static int const value = 5;


        typedef int value_type;


        ...more declarations...


    };



So, to get at the value of a numerical metafunction result, we can write:



    metafunction-name<type arguments...>::type::value



Likewise, integral constants are passed to metafunctions in similar wrappers. This extra level of indirection might seem inconvenient, but by now you can probably guess the reason for it: Requiring all metafunctions to accept and return types makes them more uniform, more polymorphic, and more interoperable. You'll see lots of examples of how this application of the FTSE pays off in the next few chapters.[5]

[5] You may have noticed that the metafunction protocol seems to prevent us from achieving the very goal that was our reason for making metafunctions polymorphic: we wanted to be able to write metafunctions that take other metafunctions as arguments. Since metafunctions are templates, not types, we can't pass them where types are expected. For now we'll just have to ask you to suspend your disbelief for the rest of this chapter; we promise to deal with that issue in Chapter 3.

All those benefits aside, writing ::type::value whenever you want to compute an actual integral constant does grow somewhat tedious. Purely as a convenience, a numerical metafunction author may decide to provide an identical nested ::value directly in the metafunction itself. All of the numerical metafunctions from the Boost library we cover in this book do just that. Note that although it's okay to take advantage of ::value when you know it's supplied by the metafunction you're calling, you can't count on a nested ::value in general, even when you know the metafunction yields a numerical result.

    Team LiB
    Previous Section Next Section