Преимущества использования boost :: mpl :: bool_ вместо const bool - PullRequest
9 голосов
/ 21 октября 2010

Я смущен преимуществами использования

bool_<true> 

и

bool_<false> 

типы против простого использования const bools в контексте шаблонного метапрограммирования.

Библиотека boost :: mpl явно предпочитает первый подход и определяет вспомогательные функции, такие как and_, or_, чтобы помочь управлять таким bool_. Условные мета-функции, такие как if_, принимают в качестве первого аргумента (шаблона) bool_, но за кулисами "вызывают" метафункцию if_c, которая ожидает (const) bool в качестве первого аргумента (шаблона).

Какие аргументы стоят за этим решением?

Заранее благодарю за помощь!

Ответы [ 3 ]

11 голосов
/ 21 октября 2010

Вот краткий пример того, как я использую эти типы время от времени. Этот пример был бы невозможен, используя 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 вы должны решить во время выполнения, какую ветку взять. Это особенно важно, если вызываемые функции сами являются шаблонами, которые не будут правильно компилироваться, если они были созданы для типов, отличных от ожидаемых, например, первое приведенное выше определение функции может содержать код, который компилируется только для указателей.

8 голосов
/ 28 ноября 2011

Это все о создании достаточно однородности, чтобы библиотека могла обеспечить полезную функциональность. Протокол 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
2 голосов
/ 21 октября 2010

Я полагаю, что одна из причин в том, что 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.

...