требуется объяснение по boost ::mpl

#c #boost #boost-mpl

#c #boost #boost-mpl

Вопрос:

 typedef vector<long,float,short,double,float,long,long double> types;
typedef fold<
      types
    , int_<0>
    , if_< is_float<_2>,next<_1>,_1 >
    >::type number_of_floats;

BOOST_MPL_ASSERT_RELATION( number_of_floats::value, ==, 4 );
  

Я не понимаю, как работает fold, почему int_<0>? почему is_float<_2> ?

Может ли кто-нибудь дать мне несколько подсказок, чтобы понять эту «функцию»? Спасибо

Ответ №1:

int_<0> это начальное значение накопителя, используемого для свертки. Попробуйте использовать int_<1> и посмотрите, что получится.

Третий аргумент — это оператор, используемый для свертывания последовательности. Это должна быть двоичная метафункция. if_< is_float<_2>,next<_1>,_1 > преобразуется в лямбда-выражение с двумя аргументами, где _1 и _2 относятся к первому и второму аргументам, которые принимает это лямбда-выражение.

Предикат is_float<_2> возвращает true, если вторым аргументом для if_ является float . _2 является заполнителем. Заполнители относятся к n-му аргументу специализации шаблона.

next<_1> просто возвращает следующее значение текущего состояния (например, next<int_<0>> == int_<1> ).

Если предикат возвращает false, мы просто возвращаем _1, который является неизмененным состоянием.

Сначала попытайтесь понять, что такое fold, затем попытайтесь понять способ boost :: mpl сделать это.

Простое упражнение заключается в написании сгиба, который возвращает длину вектора.

Комментарии:

1. просто уточнение относительно заполнителя 2 относится к n-му аргументу if или fold ? и я думаю, что это fold….

2. @guillaume07: Нет, это относится ко 2-му аргументу if_ .

3. и _1 ссылается на первый аргумент for ??

4. Нет, заполнители превращают что-то в лямбда-выражение. Таким образом, if_ принимает дополнительные аргументы. Я пытаюсь это прояснить.