Подтвердить что ты не робот

Примеры практического использования Boost:: MPL?

Можете ли вы поделиться с реальными примерами Boost:: MPL (кроме lambdas), чтобы я мог лучше понять его цели и поле практического использования? Учебник по документации MPL имеет мерный анализ, но, возможно, потому, что в таком академическом примере он не дал мне ощущение Boost:: MPL и когда это можно эффективно использовать.

4b9b3361

Ответ 1

Я использовал Boost.Mpl для создания вариантов-подобных классов.

Например, учитывая список типов MPL, например:

typedef boost::mpl::set<Foo, Bar, Baz> type_set;

Затем я использую boost::mpl::fold для построения цепочки классов, полученных из каждого другого, каждый из которых добавляет std::unordered_set одного из типов в наборе типов. Конечным результатом является класс, который содержит unordered_set<Foo>, unordered_set<Bar> и unordered_set<Baz>.

И поскольку класс указан в терминах boost::mpl::set, я могу перебирать эти типы, чтобы автоматически генерировать другие функции, такие как operator==, который сравнивает все unordered_set s.

Ответ 2

Дело в том, что Boost.MPL, например Boost.Preprocessor, действительно являются строительными блоками.

В большинстве случаев вы, вероятно, используете его через другие библиотеки, так как на этих двух сайтах построено несколько библиотек Boost.

Например:

  • Boost.Fusion(который пересекает промежутки между областями времени компиляции и времени выполнения)
  • Boost.MultiIndex(для упрощенного интерфейса)
  • Boost.Unit(для анализа размеров)
  • Boost.Variant может, я думаю, также зависит от него

Вы можете использовать его уже неизвестно:)

Ответ 3

Я использую более расширенную библиотеку анализа размеров, называемую Boost.Units.

Я разработал библиотеку отражения во времени компиляции, а затем использовал эту библиотеку для создания универсального класса, который обеспечивает отражение во время выполнения любого отраженного во времени компиляции. Я использовал эту поддержку для автоматического создания компонентов пользовательского интерфейса для редактировать свойства таких отраженных типов.

Это также имеет первостепенное значение для распределения событий в нашем приложении. Например, когда кто-то изменяет единицы, которым они хотят, чтобы система находилась внутри, мне не нужно учить эту систему, что новые элементы были добавлены к данным устройствам, потому что код использует MPL для анализа этих типов и просто знает, что что-то было добавлено и изменяет его.

Я только что использовал методы метапрограммирования, чтобы обернуть сигналы Qt во что-то, что возвращает безопасность типа, удаляемую их системой, и может подключаться к любому функциональному объекту.

Но, честно говоря, вы почти наверняка использовали практически применяемые методы метапрограммирования уже, когда вы использовали стандартные алгоритмы вроде сортировки. Достойная реализация алгоритма сортировки использует менее развитую форму метапрограммирования для анализа переданных итераторов, а затем использует диспетчеризацию меток, чтобы инициировать алгоритм сортировки, способный полностью использовать функции этих итераторов.

Совершенно откровенно, если вы не выполняете метапрограммирование, тогда вы не используете силу С++, и вы можете использовать что-то еще.

Ответ 4

Чтобы добавить к ответу Matthieu, он также довольно широко использовался во всех Boost.Python и Luabind.

Ответ 5

Я широко использую boost:: mpl (и boost:: fusion) в моей библиотеке stat_log. Эта библиотека позволяет пользователю указывать иерархию статистических и протоколирующих тегов и связанных с ними типов поведения, то есть статистических типов для каждого тега (гистограмма, счетчик и т.д.).

Я сильно полагаюсь на метапрограммирование, чтобы делать правильные действия с пользователем:

stat_log::writeStat<IP_PKTS_RCVD>(450);

Например, если пользователь определяет черту типа:

template <>
struct stat_tag_to_type<IP_PKTS_RCVD>
{
   using type = Accumulator<
        stat_log::HistogramCount<
            int,
            1, //start bin
            1500, //stop bin
            10 //num_bits
        >
     >;
};

вызов "writeStat" выше будет прокси (во время компиляции) статистике гистограммы. Мощным аспектом этой технологии проектирования является то, что сайт вызова "writeStat" не связан с выбранной конкретной статистикой.

Я также использую богатство MPL и boost:: fusion для фактического просмотра статистики. По вашему вопросу см. Следующие файлы для максимальной концентрации boost:: mpl:

https://github.com/rjmccabe3701/stat_log/blob/master/include/stat_log/util/stat_log_impl.h https://github.com/rjmccabe3701/stat_log/blob/master/include/stat_log/util/tag_commander.h https://github.com/rjmccabe3701/stat_log/blob/master/include/stat_log/stat_log.h

особенно отличная мета-функция в stat_log_impl.h:

//This template is used in conjunction with an MPL algorithm
// with the same semantics as mpl::find_if.
//BoolFunc is the "condition" metafunction.
//StatTagFunc is a metafunction that transforms the given
//   stat_tag into something the algorithm requires.
//   For example the "Identity" metafunction would work here.
//StatTagArgs is extra arguments to the BoolFunc
template <template<typename...> class BoolFunc,
          template<typename...> class StatTagFunc,
          class... StatTagArgs>
struct tag_node_query
{
   template<typename TheTagNode>
   struct apply
   {
      using stat_tag = typename TheTagNode::tag;
      using type = std::integral_constant
         <
            bool,
            BoolFunc<
               typename StatTagFunc<stat_tag>::type,
               StatTagArgs...
            >::value
         >;
   };
};

Ответ 6

Что-то смешное я сделал: https://github.com/edubois/static-factorial/blob/master/main.cpp

Он использует крошечную часть boost:: mpl для статического вычисления значения factorial < 8 > ()...

Это поможет понять основную идею.