5.7. Intrinsic Sequence Operations
MPL supplies a catalog of sequence metafunctions whose STL counterparts are usually implemented as member functions. We've already discussed begin, end, front, back, push_front, push_back, pop_front, pop_back, insert, erase, and clear; the rest are summarized in Table 5.10, where R is any sequence.
Table 5.10. Intrinsic Sequence OperationsExpression | Result | Worst-Case Complexity |
---|
mpl::empty<S>::type | A bool constant wrapper; true iff the sequence is empty. | Constant. | mpl::insert_range< S, pos, R >::type | Identical to S but with the elements of R inserted at pos. | Linear in the length of the result. | mpl::size<S>::type | An integral constant wrapper whose ::value is the number of elements in S. | Linear in the length of S. |
All of these metafunctions are known as intrinsic sequence operations, to distinguish them from generic sequence algorithms, because they generally need to be implemented separately for each new kind of sequence. They're not implemented as nested metafunctions (corresponding to similar container member functions in the STL) for three good reasons.
Syntactic overhead. Member templates are a pain to use in most metaprogramming contexts because of the need to use the extra template keyword:
Sequence::template erase<pos>::type
as opposed to:
mpl::erase<Sequence,pos>::type
As you know, reducing the burdens of C++ template syntax is a major design concern for MPL. Efficiency. Most sequences are templates that are instantiated in many different ways. The presence of template members, even if they're unused, may have a cost for each instantiation. Convenience. Despite the fact that we call these operations "intrinsic," there are reasonable ways to supply default implementations for many of them. For example, the default size measures the distance between the sequence's begin and end iterators. If these operations were member templates, every sequence author would be required to write all of them.
 |