Преимуществом других языков, таких как Python и Lisp/ Scheme, ML и Haskell и т.д., над C++ является способность иметь разнородные контейнеры, которые могут содержать произвольные типы элементов. Все контейнеры в стандартной библиотеке могут содержать только определенный тип. A vector<int>
может содержать только int
. list<X>
может содержать только элементы типа X
и так далее.
Правда, можно использовать наследование, чтобы контейнеры держали разные типы, связанные с подклассом. Тем не менее, вы должны удерживать объекты через указатель или умную ссылку какого-то рода. Делая это, вам придется полагаться на виртуальные функции, чтобы обеспечить полиморфное поведение, поскольку фактический тип стирается, как только вы храните указатель на производный класс, чтобы указать на его базу. Задержанные объекты должны быть связаны: вы не можете иметь объекты не связанных типов, таких как char
, int
, class X
, float
и т.д. О уверен, что вы можете использовать что-то вроде Boost.Any, чтобы держать произвольные типы, но затем вы платите больше с точки зрения затрат времени работы и из-за того, что вы практически стерли всю информацию типа, вам придется выполнять опасные ролики, чтобы вернуться к оригинальному типу.
Библиотека Boost.Tuple, написанная Jaakko Jarvi, предоставляет неоднородные контейнеры на C++. tuple
является базовой структурой данных, которая может содержать гетерогенные типы. Это хороший первый шаг, но он не полный. Чего не хватает, так это алгоритмов. Приятно, что мы можем хранить и извлекать данные в купле и из них, передавать их как аргументы и типы возврата. Как бы то ни было, объект Boost.Tuple уже очень полезен. Тем не менее, как только вы используете его чаще, появляются шаблоны использования. В конце концов, вы собираете эти шаблоны в библиотеки алгоритмов.
Хммм, вроде как напоминает нам о STL правильно? Точно! Можете ли вы представить, как это было бы, если бы вы использовали STL без алгоритмов? Каждый должен будет заново изобрести свои собственные колеса algorithm.
Fusion - это библиотека и структура, аналогичная как STL, так и импульсу MPL. Структура смоделирована после MPL, которая смоделирована после STL. Он называется «слияние», потому что библиотека напоминает «слияние» мета-программирования времени компиляции с программированием времени выполнения. Библиотека по своей сути имеет некоторые интересные вкусы и характеристики как MPL, так и STL. Он живет в сумеречной зоне между мета-программированием времени компиляции и программированием времени выполнения. STL контейнеры работают на значениях. Контейнеры MPL работают на типах. Контейнеры Fusion работают на обоих типах и значениях.
В отличие от MPL, алгоритмы Fusion являются ленивыми и не последовательности сохранения. Что это значит? Это означает, что когда вы работаете на последовательности через алгоритм Fusion, который возвращает последовательность, возвращенная последовательность не может быть того же класса, что и оригинал. Это по дизайну. Эффективность использования рабочего времени имеет высокий приоритет. Как и MPL, и в отличие от STL, алгоритмы синтеза являются функциональными в природе, так что алгоритмы не мутируются (без побочных эффектов). Однако из-за высокой стоимости возврата полных последовательностей, таких как векторы и списки, Views вместо этого возвращаются из алгоритмов Fusion. Например, алгоритм трансформ
фактически не возвращает преобразованную версию исходной последовательности. transform
возвращает transform_view
. Этот взгляд содержит ссылку на оригинальную последовательность плюс функцию преобразования. Итерация по transform_view
будет применять функцию преобразования по элементам последовательности по требованию. Эта схема оценки lazy позволяет нам связывать столько алгоритмов, сколько мы хотим, без применения штрафных санкций в течение длительного времени.
Схема оценки lazy, в которой алгоритмы возвращают просмотры, позволяет таким операциям, как push_back
, быть полностью общими. В Fusion push_back
на самом деле является общим алгоритмом, который работает на всех последовательностях. Учитывая последовательность ввода s
и значение x
, Fusion's push_back
алгоритм просто возвращает joint_view
: вид, который содержит ссылку на оригинальную последовательность s
и значение x
. Функции, которые когда-то были специфичны для последовательности и должны быть реализованы N раз над N различных последовательностей, теперь реализуются только один раз.
Fusion обеспечивает полную совместимость с MPL. Последовательности Fusion полностью соответствуют MPL последовательности и MPL последовательности полностью совместимы с Fusion. Вы можете работать с последовательностями Fusion на MPL если вы хотите работать исключительно на типах . В MPL последовательности Fusion следуют MPL последовательности сохранения семантики (т.е. алгоритмы сохраняют исходный тип последовательности. Например, преобразование вектора возвращает вектор. Вы также можете преобразовать из последовательности MPL в последовательность Fusion. Например, бывают случаи, когда удобно работать исключительно на MPL используя чистые последовательности MPL, затем конвертировать их в последовательности Fusion как последний шаг перед фактическим мгновенным отображением объектов реального времени с данными. У вас есть лучшее из обоих миров.