Преимущества с помощью Boost::МПЛ::типа bool, а не константный боол
Я смущен преимуществами использования
bool_<true>
и
bool_<false>
типы против простого использования const bools в контексте метапрограммирования шаблонов.
библиотека boost::mpl явно предпочитает первый подход и определяет вспомогательные функции, такие как and_, or_, чтобы помочь управлять таким bool_. Условные метафункции, такие как if_, "принимают" bool_ в качестве первого аргумента (шаблона), но за кулисами "вызывают" метафункцию if_c, которая ожидает (const) bool как первый (шаблон) аргумент.
каковы аргументы в пользу этого решения?
заранее спасибо за вашу помощь!
3 ответов
вот краткий пример того, как я использую эти типы время от времени. Этот пример был бы невозможен, используя const bool:
void do_something(boost::mpl::bool_<true>)
{
...
}
void do_something(boost::mpl::bool_<false>)
{
...
}
вызов одной из этих двух функций в зависимости от типа аргумента:
template<class T>
void doIt(void)
{
do_something(boost::mpl::bool_<boost::is_pointer<T>::val>())
}
в этом случае будет вызвана первая или вторая функция, в зависимости от того, является ли тип T указателем или нет. Эти типы позволяют использовать перегрузку функций, где было бы невозможно использовать const bool. С const bool вы придется решать во время выполнения, какую ветку взять. Это особенно важно, если вызываемые функции сами являются шаблонами, которые не будут компилироваться правильно, если они были созданы для типов, отличных от ожидаемых, например, первое определение функции выше может содержать код, который компилируется только для указателей.
это все о создании достаточного единообразия, что библиотека может обеспечить полезную функциональность. Протокол MPL: "все аргументы метафункции (и возвращает) являются типами."Это позволяет нам писать шаблоны, которые могут работать в целом на метафункциях. Например, этот шаблон принимает любую метафункцию (или любую метафункцию С до N аргументами в C++03):
template <template <class...> class some_metafunction>
struct wrapper;
как только вы разрешите некоторым аргументам шаблона быть не-типами, написание такой оболочки становится невозможно. Для практического примера того, почему мы заботимся, это единообразие позволяет библиотеке выбирать и оценивать лямбда-выражения MPL. Если бы аргументам метафункции было разрешено быть не-типами, эта функция была бы невосполнима, потому что не было бы возможности записать все частичные специализации, необходимые для распутывания внешнего шаблона xxx
из его аргументов a
Я на xxx<a1,a2,a3,...>
.
менее интересная, если не менее действительная, часть причины заключается в том, что многие вещи становятся менее многословными, как мы сделали это в MPL. сравнить:
and_<mf0<x,y>, mf1<z>, mf2<x,z> >::value
vs
mf0<x,y>::value && mf1<z>::value && mf2<x,z>::value
Я полагаю, одна из причин этого bool_<...>
являются типами, и при использовании их в качестве результатов мета-функций вам никогда не придется останавливаться и думать, является ли ваш результат типом, и вам нужно сделать
typedef some_type result;
или значение, которое должно быть возвращено как
const static ??? result = some_value;
где вы также должны отслеживать тип.
кроме того, я подозреваю (я не работал с Boost.MPL еще), что у них обоих есть result
введите вложенные ссылки на себя, чтобы вы могли напишите мета-функции, просто выводя из них:
template< bool b >
struct my_meta_func : bool_<b> {};
и может вызвать my_meta_func::result
.