Это все о создании достаточно однородности, чтобы библиотека могла обеспечить полезную функциональность. Протокол MPL: «все аргументы метафункций (и возвращаемые) являются типами». Это позволяет нам писать шаблоны, которые могут работать с метафункциями. Например, этот шаблон принимает любую метафункцию (или любую метафункцию с максимум N аргументами в C ++ 03):
template <template <class...> class some_metafunction>
struct wrapper;
После того, как вы позволите некоторым из аргументов шаблона быть нетипичными, написание такой оболочки становится невозможным. Для практического примера того, почему мы заботимся, эта единообразие позволяет библиотеке выбирать и оценивать лямбда-выражения MPL. Если бы аргументы мета-функции были разрешены как нетиповые, эта функция была бы неосуществимой, потому что не было бы способа выписать все частичные специализации, необходимые для распутывания внешнего шаблона xxx
из его аргументов a
i в xxx<a1,a2,a3,...>
.
Менее интересная, если не менее обоснованная, причина в том, что многие вещи становятся менее многословными, как мы это делали в MPL. Для сравнения:
and_<mf0<x,y>, mf1<z>, mf2<x,z> >::value
против
mf0<x,y>::value && mf1<z>::value && mf2<x,z>::value