2.3. Numerical MetafunctionsYou 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]
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. ![]() |