2013-12-17 4 views
2

Ive провело день, читая заметки и смотря видео на boost :: fusion, и я действительно не понимаю его.Какова цель boost :: fusion?

Возьмем, к примеру, функцию boost::fusion::has_key<S>. Какова цель этого в boost :: fusion? Является ли идея, что мы просто пытаемся переместить как можно больше программирования во время компиляции? Так что любая функция boost::fusion такая же, как и во время выполнения, за исключением того, что она теперь оценивается во время компиляции? (и мы предполагаем, что делать больше во время компиляции хорошо?).

Связано с boost :: fusion, я также немного смущен, почему метафайлы всегда возвращают типы. Почему это?

+6

Я бы скорее обнаружил ошибку во время компиляции, чем во время выполнения. –

+0

Является ли STL для кортежей. Если вы сопоставляете классы с кортежами, вы можете использовать его для отражения во времени компиляции. – gnzlbg

ответ

2

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

Возвращает типы мета-функций, потому что мета-программирование шаблонов не было специально создано. Было обнаружено более или менее случайно, что шаблоны C++ могут использоваться как язык программирования компиляции. Мета-функция - это сопоставление от аргументов шаблона до экземпляров шаблона. С C++ 03 были два типа шаблона (class- и function-), поэтому мета-функция должна «возвращать» либо класс, либо функцию. Классы более полезны, чем функции, поскольку вы можете поместить значения и т. Д. В свои статические члены данных.

C++ 11 добавляет другой тип шаблона (для typedefs), но это не имеет никакого отношения к метапрограммированию. Что еще более важно для программирования во время компиляции, C++ 11 добавляет функции constexpr. Они правильно разработаны для этой цели, и они возвращают значения, как обычные функции. Конечно, их ввод не является типом, поэтому они не могут быть сопоставлениями от типов к чему-то другому в способе, которым могут пользоваться шаблоны. Таким образом, в этом смысле им не хватает «мета-» части метапрограмм. Это «просто» компиляция времени обычных функций C++, а не мета-функций.

4

Еще один способ взглянуть на boost :: fusion - это подумать об этом как о библиотеке «самоанализа бедных». Оригинальная мотивация boost :: fusion исходит из направления boost :: spirit parser/generator framework, в частности, для поддержки того, что называется атрибутами парсера.

Представьте, у вас есть строка CSV для анализа:

Аааа, 1,1

типа, эта строка разбирает в, может быть описана как «кортеж строки и двойной» , Мы можем определить такие кортежи в «plain» C++, либо со старыми школьными структурами (struct { string a; double b; }, либо новее tuple<string, double>). Единственное, что мы пропустили, это какой-то адаптер, который позволит передавать кортежи (и некоторые другие типы) произвольного состава в унифицированный интерфейс синтаксического анализатора и ожидать, что он будет разбираться в этом без передачи какой-либо внеполосной информации (например, строки шаблоны синтаксического анализа, используемые scanf).

Вот где boost :: fusion вступает в игру.Самый простой способ построить «последовательность фьюжн», чтобы адаптировать нормальный-структуру:

struct a { 
    string s; 
    double d; 
}; 
BOOST_FUSION_ADAPT_STRUCT(a, (string, s)(double, d)) 

«ADAPT_STRUCT» макрос добавляет необходимую информацию для структуры синтаксического анализатора (в данном примере), чтобы иметь возможность «итерация» над члены struct a к мелодии на следующие вопросы:

  1. Я просто разобран строку. Могу ли я назначить его первому члену struct a?

  2. Я просто разобрал двойной. Могу ли я назначить его второму члену struct a?

  3. Есть ли другие члены в struct a или я должен прекратить разбор?

Очевидно, что этот простой пример может быть продлен (и повышение :: фьюжн поставляет способность) для решения гораздо более сложные случаи:

  1. Варианты - скажем, анализатор может столкнуться либо жала или double и хочет присвоить его правильному члену struct a. BOOST_FUSION_ADAPT_ASSOC_STRUCT приходит на помощь (теперь наш синтаксический анализатор может задавать вопросы типа «какой член struct a имеет тип double?»).

  2. Преобразования - наш анализатор может быть разработан, чтобы принимать определенные типы в качестве параметров, но остальные программы сильно изменились. Тем не менее, фьюжн-метафунды можно удобно использовать для адаптации новых типов к старым реалиям (или наоборот).

Остальные функции boost :: fusion, естественно, вытекают из вышеуказанных основ. fusion действительно сияет, когда необходимо преобразовать (в любом направлении) «свободные данные IO» в строго типизированные/структурированные данные, на которых действуют программы на C++ (если эффективность вызывает беспокойство). Это фактор, обеспечивающий дух: qi и spirit :: karma - такая эффективная (возможно, самая быстрая) инфраструктура ввода-вывода.