![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
THE BOOST MPL LIBRARY: Implementing DivisionBoost , ,
|
Front Page / Tutorial: Metafunctions and Higher-Order Metaprogramming / Dimensional Analysis / Implementing Division |
Отдел похож на умножение, но вместо добавления экспонентов мы должны вычесть их. Вместо того, чтобы писать почти дубликат плюс_f, мы можем использовать следующий трюк, чтобы сделать minus_f гораздо проще:
struct minus_f { template <class T1, class T2> struct apply : mpl::minus<T1,T2> {}; };
Здесь minus_f::apply использует наследование, чтобы разоблачить вложенное тип своего базового класса, mpl::minus, поэтому нам не нужно писать:
typedef typename ...::type type
Нам не нужно писать typename здесь (на самом деле, это было бы незаконно), потому что компилятор знает, что зависимые имена в apply инициализатор списка должны быть базовыми классами. [2] Это мощное упрощение известно как передача функции; мы будем применять его часто, когда книга продолжается. [3]
[2] | Если вам интересно, тот же подход мог быть применен к плюс_f, но поскольку он немного тонкий, мы ввели простую, но глаголную формулировку сначала. |
[3] | Пользователи компиляторов на основе EDG должны проконсультироваться Книга Приложение С для опровержения метафункций. Вы можете сказать, есть ли у вас компилятор EDG, проверив предпроцессорный символ __EDG_VERSION__, который определяется всеми компиляторами на основе EDG. |
Несмотря на синтаксические трюки, писать тривиальные классы, чтобы обернуть существующие метафуны, будет довольно быстро скучно. Несмотря на то, что определение minus_f было гораздо менее глаголом, чем определение плюс_f, его все еще очень много. К счастью, MPL дает нам much простой способ передачи метафункций. Вместо построения целого класса метафункций мы можем вызвать трансформ таким образом:
typename mpl::transform<D1,D2, mpl::minus<_1,_2> >::type
Эти забавные выглядящие аргументы (_1 и _2) известны как заменители, и они означают, что когда трансформ BinaryOperation используется, его первый и второй аргументы будут переданы minus в позициях, указанных _1 и _2>. Весь тип mpl::minus<_1,_2> известен как выражение place.
Note
Владельцы мест MPL находятся в mpl::placeholders namespace и определены в boost/mpl/placeholders.hpp. В этой книге мы обычно предполагаем, что вы написали:
#include<boost/mpl/placeholders.hpp> using namespace mpl::placeholders;
чтобы к ним можно было получить доступ без квалификации.
Вот наш оператор подразделения, написанный с использованием выражений помещика:
template <class T, class D1, class D2> quantity< T , typename mpl::transform<D1,D2,mpl::minus<_1,_2> >::type > operator/(quantity<T,D1> x, quantity<T,D2> y) { typedef typename mpl::transform<D1,D2,mpl::minus<_1,_2> >::type dim; return quantity<T,dim>( x.value() / y.value() ); }
Этот код значительно проще. Мы можем упростить его еще дальше, указав код, который вычисляет новые измерения в свою собственную метафункцию:
template <class D1, class D2> struct divide_dimensions : mpl::transform<D1,D2,mpl::minus<_1,_2> > // forwarding again {}; template <class T, class D1, class D2> quantity<T, typename divide_dimensions<D1,D2>::type> operator/(quantity<T,D1> x, quantity<T,D2> y) { return quantity<T, typename divide_dimensions<D1,D2>::type>( x.value() / y.value()); }
Теперь мы можем проверить наши вычисления " Force-on-a-laptop " , обратив их вспять:
quantity<float,mass> m2 = f/a; float rounding_error = std::abs((m2 - m).value());
Если у нас все в порядке, кругление_error должно быть очень близко к нулю. Это скучные расчеты, но это просто то, что может испортить целую программу (или, что еще хуже), если вы ошибаетесь. Если бы мы написали a/f вместо f/a, была бы ошибка компиляции, предотвращающая распространение ошибки на протяжении всей нашей программы.
Статья THE BOOST MPL LIBRARY: Implementing Division раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::
реклама |