![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
THE BOOST MPL LIBRARY: Incomplete Support for Lambda ExpressionsBoost , ,
|
Front Page / Technical Details / Portability / Incomplete Support for Lambda Expressions |
Опытные пользователи MPL согласятся с нами, что если в MPL есть что-то магическое, как по силе, так и по своей природе, то это лямбда-выражения MPL. На самом деле механизм, который воплощает это в жизнь, очень прост и, вероятно, может быть объяснен любому, кто знаком с шаблонами C++ менее чем за 10 минут.
К сожалению, этот механизм также опирается на поддержку частичной специализации шаблонов и параметров шаблонов шаблонов. Среди так называемых неполноценных компиляторов — в основном, большинство компиляторов, выпущенных до 2000 года — шансы на то, что вы найдетеполную поддержкудляобеихэтих функций, невелики. Пожалуйста, ознакомьтесь с нашей таблицейсовместимостидля списка продуктов, которые попадают в эту категорию.
Хотя невозможно реализоватьполностью прозрачныелямбда-выражения без этих двух функций, возможна немного более ограниченная реализация, требующая некоторой ручной помощи от автора метафункции. В этом разделе описывается требуемая ручная работа и ограничения результата.
Если ваш компилятор попадает в категорию "недостаток", следующая действующая метапрограмма MPL не будет компилироваться для вас:
#include <boost/mpl/apply.hpp> using namespace boost::mpl; template< typename T > struct add_const { typedef T const type; }; typedef apply1< add_const<_1>,int >::type t; // t == int const
Хуже того, скорее всего, это не удастся с диагностическим фоном, ведущим вас внутрь библиотеки и, возможно, создающим впечатление, что там что-то не так. Дело в том, что и программа, и библиотека не имеют дефектов (для этой конкретной демонстрации), и виноват в этом ваш компилятор.
Как упоминалось ранее, решение требует некоторой работы от авторов метафункций, но для пользователей этих метафункций результат относительно прозрачен. Вот что мы должны сделать с нашим предыдущим примером:
#include <boost/mpl/apply.hpp> #include <boost/mpl/aux_/lambda_support.hpp> using namespace boost::mpl; template< typename T > struct add_const { typedef T const type; BOOST_MPL_AUX_LAMBDA_SUPPORT(1, add_const, (T)) }; typedef apply1< add_const<_1>,int >::type t; // t == int const
С этими двумя модификациями теперь компилятор, лающий на нас, с радостью принимает его. "Эй, это совсем не плохо! "Вы можете сказать. Просто положите немного макроса внутрь и снова будьте счастливы.
К сожалению, это не совсем конец истории. Есть еще случаи, когда вышеописанный подход не сработает, и нам придется прибегнуть к написанию заочного класса метафункций. Вот подробности:
Чтобы выражение лямбда работало без частичной специализации шаблона и параметров шаблонного шаблона, MPL должен реализовать какой-то другой способ разъединения дерева экспрессии шаблонных инстанциаций, и единственный способ сделать это - через интрузивный механизм интроспекции метафункций. Вот что скрывается заBOOST_MPL_AUX_LAMBDA_SUPPORTМакро мы видели выше.
Но затем, после того, как мы получили необходимую нам информацию (пространство метафункции и ее точные аргументы шаблона), хранящуюся внутри самой метафункции, единственный способ получить к ней доступ — это заглянуть внутрь метафункции. Последнее, в свою очередь, означает преждевременное инстанцирование метафункции до фактического вызовас одним или несколькими аргументами заполнителя. Последняя часть является потенциальной проблемой.
Другими словами, механизм работает до тех пор, пока ваша метафункция является "заполнитель-безопасный" (можно безопасно инстанцироваться на аргументах заполнителя), что сводится к двум критериям:
Если эти два держатся, вы можете безопасно положить.BOOST_MPL_AUX_LAMBDA_SUPPORTвнутри вашей метафункции и забудьте о проблеме. Если нет, то вам не повезло, и вам, вероятно, придется написать класс метафункций.
Хорошей новостью является то, что большинство собственных метафункций MPL иBoost. Шаблоны Type Traitsявляются "безопасными для владельца места" и к ним применяется обходной путь, поэтому даже на сломанных компиляторах вещи"просто работают" примерно в 90% случаев использования.
Пожалуйста, обратитесь к справочному руководству MPLдля получения подробной информации о.BOOST_MPL_AUX_LAMBDA_SUPPORTМакро.
Статья THE BOOST MPL LIBRARY: Incomplete Support for Lambda Expressions раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::
реклама |