Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Examples

Boost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 40. Boost.Units 1.1.0

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

dimension.cpp

Используя метафункции MPL и шаблонные специализации для операций по композитным измерениям (определяется в<boost/units/dimension.hpp>), можно выполнить компиляцию арифметики времени в соответствии с правилами размерного анализа, описаннымивыше, для получения новых композитных измерений:

typedef mpl::times<length_dimension,mass_dimension>::type   LM_type;
typedef mpl::divides<length_dimension,time_dimension>::type L_T_type;
typedef static_root<
    mpl::divides<energy_dimension,mass_dimension>::type,
    static_rational<2>
>::type    V_type;

вывод (с демонтажем символа, реализованный вutility.hpp)

length_dimension  = list<dim<length_base_dimension, static_rational<1l, 1l> >, dimensionless_type>
mass_dimension    = list<dim<mass_base_dimension, static_rational<1l, 1l> >, dimensionless_type>
time_dimension    = list<dim<time_base_dimension, static_rational<1l, 1l> >, dimensionless_type>
energy_dimension  = list<dim<length_base_dimension, static_rational<2l, 1l> >, list<dim<mass_base_dimension, static_rational<1l, 1l> >, list<dim<time_base_dimension, static_rational<-2l, 1l> >, dimensionless_type> > >
LM_type      = list<dim<length_base_dimension, static_rational<1l, 1l> >, list<dim<mass_base_dimension, static_rational<1l, 1l> >, dimensionless_type> >
L_T_type     = list<dim<length_base_dimension, static_rational<1l, 1l> >, list<dim<time_base_dimension, static_rational<-1l, 1l> >, dimensionless_type> >
V_type       = list<dim<length_base_dimension, static_rational<1l, 1l> >, list<dim<time_base_dimension, static_rational<-1l, 1l> >, dimensionless_type> >

unit.cpp

Этот пример демонстрирует использование простой, но функциональной системы блоков, реализованной вtest_system.hpp

const length                    L;
const mass                      M;
// needs to be namespace-qualified because of global time definition
const boost::units::test::time  T;
const energy                    E;

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

L             = m
L+L           = m
L-L           = m
L/L           = dimensionless
meter*meter   = m^2
M*(L/T)*(L/T) = m^2 kg s^-2
M*(L/T)^2     = m^2 kg s^-2
L^3           = m^3
L^(3/2)       = m^(3/2)
2vM           = kg^(1/2)
(3/2)vM       = kg^(2/3)

количество.cpp

Этот пример показывает, как использовать количество нашей системы игрушек:

quantity<length> L = 2.0*meters;                     // quantity of length
quantity<energy> E = kilograms*pow<2>(L/seconds);    // quantity of energy

Дайте нам основную количественную функциональность:

L                                 = 2 m
L+L                               = 4 m
L-L                               = 0 m
L*L                               = 4 m^2
L/L                               = 1 dimensionless
L*meter                           = 2 m^2
kilograms*(L/seconds)*(L/seconds) = 4 m^2 kg s^-2
kilograms*(L/seconds)^2           = 4 m^2 kg s^-2
L^3                               = 8 m^3
L^(3/2)                           = 2.82843 m^(3/2)
2vL                               = 1.41421 m^(1/2)
(3/2)vL                           = 1.5874 m^(2/3)

В качестве еще одной демонстрации гибкости системы мы заменяем тип значений<double>на тип значений<std::complex<double>>(игнорируя вопрос о значении сложных длин и энергий):

quantity<length,std::complex<double> > L(std::complex<double>(3.0,4.0)*meters);
quantity<energy,std::complex<double> > E(kilograms*pow<2>(L/seconds));

и найти, что код функционирует точно так, как ожидалось, без дополнительной работы, делегируя операции<std::complex<double>>и выполняя соответствующий размерный анализ:

L                                 = (3,4) m
L+L                               = (6,8) m
L-L                               = (0,0) m
L*L                               = (-7,24) m^2
L/L                               = (1,0) dimensionless
L*meter                           = (3,4) m^2
kilograms*(L/seconds)*(L/seconds) = (-7,24) m^2 kg s^-2
kilograms*(L/seconds)^2           = (-7,24) m^2 kg s^-2
L^3                               = (-117,44) m^3
L^(3/2)                           = (2,11) m^(3/2)
2vL                               = (2,1) m^(1/2)
(3/2)vL                           = (2.38285,1.69466) m^(2/3)

kitchen_sink.cpp

Этот пример дает довольно обширный набор тестов, охватывающих большую часть.<quantity>Функциональность. Он использует систему единиц СИ, определенную в<boost/units/systems/si.hpp>.

Если мы определим несколько единиц и соответствующие величины,

/// scalar
const double    s1 = 2;
const long                  x1 = 2;
const static_rational<4,3>  x2;
/// define some units
force       u1 = newton;
energy      u2 = joule;
/// define some quantities
quantity<force>      q1(1.0*u1);
quantity<energy>     q2(2.0*u2);

Различные алгебраические операции между скалярами, единицами и величинами дают

S1 :    2
X1 :    2
X2 :    (4/3)
U1 :    N
U2 :    J
Q1 :    1 N
Q2 :    2 J

Скалярные/единичные операции:

U1*S1 : 2 N
S1*U1 : 2 N
U1/S1 : 0.5 N
S1/U1 : 2 m^-1 kg^-1 s^2

Операции единицы/единицы и интегральные/рациональные полномочия единиц:

U1+U1 : N
U1-U1 : N
U1*U1 : m^2 kg^2 s^-4
U1/U1 : dimensionless
U1*U2 : m^3 kg^2 s^-4
U1/U2 : m^-1
U1^X  : m^2 kg^2 s^-4
X1vU1 : m^(1/2) kg^(1/2) s^-1
U1^X2 : m^(4/3) kg^(4/3) s^(-8/3)
X2vU1 : m^(3/4) kg^(3/4) s^(-3/2)

Скалярные/количественные операции:

Q1*S1 : 2 N
S1*Q1 : 2 N
Q1/S1 : 0.5 N
S1/Q1 : 2 m^-1 kg^-1 s^2

Единичные/количественные операции:

U1*Q1 : 1 m^2 kg^2 s^-4
Q1*U1 : 1 m^2 kg^2 s^-4
U1/Q1 : 1 dimensionless
Q1/U1 : 1 dimensionless

Количество/количественные операции и интегральные/рациональные возможности величин:

+Q1   : 1 N
-Q1   : -1 N
Q1+Q1 : 2 N
Q1-Q1 : 0 N
Q1*Q1 : 1 m^2 kg^2 s^-4
Q1/Q1 : 1 dimensionless
Q1*Q2 : 2 m^3 kg^2 s^-4
Q1/Q2 : 0.5 m^-1
Q1^X1 : 1 m^2 kg^2 s^-4
X1vQ1 : 1 m^(1/2) kg^(1/2) s^-1
Q1^X2 : 1 m^(4/3) kg^(4/3) s^(-8/3)
X2vQ1 : 1 m^(3/4) kg^(3/4) s^(-3/2)

Логические операторы сравнения также определяются между величинами:

/// check comparison tests
quantity<length>    l1(1.0*meter),
                    l2(2.0*meters);

давать

l1 == l2    false
l1 != l2    true
l1 <= l2    true
l1 < l2     true
l1 >= l2    false
l1 > l2     false

Допускается неявное преобразование между безразмерными величинами и их соответствующими типами значений:

/// check implicit unit conversion from dimensionless to value_type  
const double    dimless = (q1/q1);

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

/// the physical definition of work - computed for an arbitrary unit system 
template<class System,class Y>
quantity<unit<energy_dimension,System>,Y>
work(quantity<unit<force_dimension,System>,Y> F,
     quantity<unit<length_dimension,System>,Y> dx)
{
    return F*dx;
}

/// test calcuation of work
quantity<force>       F(1.0*newton);
quantity<length>      dx(1.0*meter);
quantity<energy>      E(work(F,dx));

которые функционируют так, как ожидается для величин СИ:

F  = 1 N
dx = 1 m
E  = 1 J

Закон об идеальном газе также может быть реализован в единицах СИ:

/// the ideal gas law in si units
template<class Y>
quantity<si::amount,Y>
idealGasLaw(const quantity<si::pressure,Y>& P,
            const quantity<si::volume,Y>& V,
            const quantity<si::temperature,Y>& T)
{
    using namespace boost::units::si;
    using namespace constants::codata;
    return (P*V/(R*T));
}

/// test ideal gas law
quantity<temperature>   T = (273.+37.)*kelvin;
quantity<pressure>      P = 1.01325e5*pascals;
quantity<length>        r = 0.5e-6*meters;
quantity<volume>        V = (4.0/3.0)*3.141592*pow<3>(r);
quantity<amount>        n(idealGasLaw(P,V,T));

с полученным выходом:

r = 5e-07 m
P = 101325 Pa
V = 5.23599e-19 m^3
T = 310 K
n = 2.05835e-17 mol
R = 8.314472 m^2 kg s^-2 K^-1 mol^-1 (rel. unc. = 1.8e-06)

Тригонометрические и обратные тригонометрические функции могут быть реализованы для любой модульной системы, обеспечивающей угловое базовое измерение. Для радианов эти функции встречаются в<boost/units/cmath.hpp>. Они ведут себя, как и ожидалось, с тригонометрическими функциями, принимающими угловую величину и возвращающими безразмерную величину, в то время как обратные тригонометрические функции берут безразмерную величину и возвращают угловую величину:

Определение нескольких угловых величин,

/// test trig stuff
quantity<plane_angle>           theta = 0.375*radians;
quantity<dimensionless>         sin_theta = sin(theta);
quantity<plane_angle>           thetap = asin(sin_theta);

доходность

theta            = 0.375 rd
sin(theta)       = 0.366273 dimensionless
asin(sin(theta)) = 0.375 rd

Работа со сложными количествами тривиальна. Вот расчет сложного импеданса:

quantity<electric_potential,complex_type> v = complex_type(12.5,0.0)*volts;
quantity<current,complex_type>            i = complex_type(3.0,4.0)*amperes;
quantity<resistance,complex_type>         z = complex_type(1.5,-2.0)*ohms;

давать

V   = (12.5,0) V
I   = (3,4) A
Z   = (1.5,-2) Ohm
I*Z = (12.5,0) V

Определенные пользователем типы значений, которые поддерживают соответствующие арифметические операции, автоматически поддерживаются в качестве типов величин. Операторы, которые поддерживаются по умолчанию для типов количественных значений, являются унарными плюсами, унарными минусами, сложением, вычитанием, умножением, делением, равными, не равными, менее чем, менее или равными, более чем и более или равными. Поддержка рациональных сил и корней может быть добавлена перегрузкой классов<power_typeof_helper>и<root_typeof_helper>. Здесь мы реализуем класс, определяемый пользователем<measurement>, который моделирует численное измерение с соответствующей погрешностью измерения и соответствующей алгеброй и демонстрирует его использование в качестве типа величины; полный код находится вmeasurement.hpp.

Затем, определив некоторые<measurement><quantity>переменные

quantity<length,measurement<double> >
    u(measurement<double>(1.0,0.0)*meters),
    w(measurement<double>(4.52,0.02)*meters),
    x(measurement<double>(2.0,0.2)*meters),
    y(measurement<double>(3.0,0.6)*meters);

давать

x+y-w         = 0.48(+/-0.632772) m
w*x           = 9.04(+/-0.904885) m^2
x/y           = 0.666667(+/-0.149071) dimensionless

Если мы реализуем перегруженные классы помощников для рациональных сил и корней, то мы также можем вычислить рациональные силы величин измерения.

w*y^2/(u*x)^2 = 10.17(+/-3.52328) m^-1
w/(u*x)^(1/2) = 3.19612(+/-0.160431) dimensionless

conversion.cpp

Этот пример демонстрирует различные разрешенные конверсии между SI и CGS. Определение некоторых величин

quantity<si::length>     L1 = quantity<si::length,int>(int(2.5)*si::meters);
quantity<si::length,int> L2(quantity<si::length,double>(2.5*si::meters));

иллюстрирует неявное преобразование величин различных типов значений, где допускается неявное преобразование самих типов значений. N.B. Преобразование из двойного в int рассматривается как явное преобразование, потому что нет способа эмулировать точное поведение встроенного преобразования. Конструкторы допускают конверсию для двух случаев:

quantity<si::length,int> L3 = static_cast<quantity<si::length,int> >(L1);

quantity<cgs::length>    L4 = static_cast<quantity<cgs::length> >(L1);

давая следующий результат:

L1 = 2 m
L2 = 2 m
L3 = 2 m
L4 = 200 cm
L5 = 5 m
L6 = 4 m
L7 = 200 cm

Несколько более явных преобразований системы блоков:

quantity<si::volume>    vs(1.0*pow<3>(si::meter));
quantity<cgs::volume>   vc(vs);
quantity<si::volume>    vs2(vc);
quantity<si::energy>    es(1.0*si::joule);
quantity<cgs::energy>   ec(es);
quantity<si::energy>    es2(ec);
quantity<si::velocity>  v1 = 2.0*si::meters/si::second,
                        v2(2.0*cgs::centimeters/cgs::second);

который производит следующую продукцию:

volume (m^3)  = 1 m^3
volume (cm^3) = 1e+06 cm^3
volume (m^3)  = 1 m^3
energy (joules) = 1 J
energy (ergs)   = 1e+07 erg
energy (joules) = 1 J
velocity (2 m/s)  = 2 m s^-1
velocity (2 cm/s) = 0.02 m s^-1

quaternion.cpp

Этот пример демонстрирует использование<boost::math::quaternion>в качестве типа значения для<quantity>и обратного. Для первого случая мы сначала определяем специализации<power_typeof_helper>и<root_typeof_helper>для степеней и корней, соответственно:

/// specialize power typeof helper
template<class Y,long N,long D>
struct power_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
{
    // boost::math::quaternion only supports integer powers
    BOOST_STATIC_ASSERT(D==1);
    typedef boost::math::quaternion<
        typename power_typeof_helper<Y,static_rational<N,D> >::type
    > type;
    static type value(const boost::math::quaternion<Y>& x)
    {
        return boost::math::pow(x,static_cast<int>(N));
    }
};

/// specialize root typeof helper
template<class Y,long N,long D>
struct root_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
{
    // boost::math::quaternion only supports integer powers
    BOOST_STATIC_ASSERT(N==1);
    typedef boost::math::quaternion<
        typename root_typeof_helper<Y,static_rational<N,D> >::type
    > type;
    static type value(const boost::math::quaternion<Y>& x)
    {
        return boost::math::pow(x,static_cast<int>(D));
    }
};

Теперь мы можем объявить<quantity><quaternion>:

typedef quantity<length,quaternion<double> >     length_dimension;
length_dimension    L(quaternion<double>(4.0,3.0,2.0,1.0)*meters);

Таким образом, все операции, определенные в классе<quaternion>, ведут себя правильно. Если бы для этого класса были определены рациональные силы, можно было бы вычислить рациональные силы и корни без каких-либо дополнительных изменений.

+L      = (4,3,2,1) m
-L      = (-4,-3,-2,-1) m
L+L     = (8,6,4,2) m
L-L     = (0,0,0,0) m
L*L     = (2,24,16,8) m^2
L/L     = (1,0,0,0) dimensionless
L^3     = (-104,102,68,34) m^3

Если бы мы по каким-то причинам предпочли<quantity>классу<quaternion>, мы бы имели:

typedef quaternion<quantity<length> >     length_dimension;
length_dimension    L(4.0*meters,3.0*meters,2.0*meters,1.0*meters);

Здесь правильно функционируют унарные плюс-минус и операторы сложения и вычитания. К сожалению, операции умножения и деления терпят неудачу, потому что<quaternion>реализует их в терминах операторов<*=>и</=>соответственно, которые неспособны представлять гетерогенную единицу алгебры, необходимую для величин (идентичная проблема возникает с<std::complex<T>>, по той же причине). Чтобы вычислить рациональные силы и корни, нам нужно специализироваться<power_typeof_helper>и<root_typeof_helper>следующим образом:

/// specialize power typeof helper for quaternion<quantity<Unit,Y> >
template<class Unit,long N,long D,class Y>
struct power_typeof_helper<
    boost::math::quaternion<quantity<Unit,Y> >,
    static_rational<N,D> >
{
    typedef typename power_typeof_helper<
        Y,
        static_rational<N,D>
    >::type     value_type;
    typedef typename power_typeof_helper<
        Unit,
        static_rational<N,D>
    >::type  unit_type;
    typedef quantity<unit_type,value_type>         quantity_type;
    typedef boost::math::quaternion<quantity_type> type;
    static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)
    {
        const boost::math::quaternion<value_type>   tmp =
            pow<static_rational<N,D> >(boost::math::quaternion<Y>(
                x.R_component_1().value(),
                x.R_component_2().value(),
                x.R_component_3().value(),
                x.R_component_4().value()));
        return type(quantity_type::from_value(tmp.R_component_1()),
                    quantity_type::from_value(tmp.R_component_2()),
                    quantity_type::from_value(tmp.R_component_3()),
                    quantity_type::from_value(tmp.R_component_4()));
    }
};

/// specialize root typeof helper for quaternion<quantity<Unit,Y> >
template<class Unit,long N,long D,class Y>
struct root_typeof_helper<
    boost::math::quaternion<quantity<Unit,Y> >,
    static_rational<N,D> >
{
    typedef typename root_typeof_helper<
        Y,
        static_rational<N,D>
    >::type      value_type;
    typedef typename root_typeof_helper<
        Unit,
        static_rational<N,D>
    >::type   unit_type;
    typedef quantity<unit_type,value_type>         quantity_type;
    typedef boost::math::quaternion<quantity_type> type;
    static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)
    {
        const boost::math::quaternion<value_type>   tmp =
            root<static_rational<N,D> >(boost::math::quaternion<Y>(
                x.R_component_1().value(),
                x.R_component_2().value(),
                x.R_component_3().value(),
                x.R_component_4().value()));
        return type(quantity_type::from_value(tmp.R_component_1()),
                    quantity_type::from_value(tmp.R_component_2()),
                    quantity_type::from_value(tmp.R_component_3()),
                    quantity_type::from_value(tmp.R_component_4()));
    }
};

давать:

+L      = (4 m,3 m,2 m,1 m)
-L      = (-4 m,-3 m,-2 m,-1 m)
L+L     = (8 m,6 m,4 m,2 m)
L-L     = (0 m,0 m,0 m,0 m)
L^3     = (-104 m^3,102 m^3,68 m^3,34 m^3)

complex.cpp

Этот пример показывает, как реализовать класс замены<complex>, который функционирует правильно как тип величины, так и класс контейнера количества, включая гетерогенные операции умножения и деления и рациональные силы и корни. Естественно, гетерогенные операции поддерживаются только на компиляторах, реализующих<typeof>. Основные различия заключаются в том, что двоичные операции не реализуются с использованием операторов<op=>и используют классы полезности<add_typeof_helper>,<subtract_typeof_helper>,<multiply_typeof_helper>и<divide_typeof_helper>. Кроме того,<power_typeof_helper>и<root_typeof_helper>определены для обоих случаев:

namespace boost {
namespace units {
/// replacement complex class 
template<class T>
class complex
{
    public:
        typedef complex<T>  this_type;
        complex(const T& r = 0,const T& i = 0) : r_(r),i_(i) { }
        complex(const this_type& source) : r_(source.r_),i_(source.i_) { }
        this_type& operator=(const this_type& source)
        {
            if (this == &source) return *this;
            r_ = source.r_;
            i_ = source.i_;
            return *this;
        }
        T& real()                   { return r_; }
        T& imag()                   { return i_; }
        const T& real() const       { return r_; }
        const T& imag() const       { return i_; }
        this_type& operator+=(const T& val)
        {
            r_ += val;
            return *this;
        }
        this_type& operator-=(const T& val)
        {
            r_ -= val;
            return *this;
        }
        this_type& operator*=(const T& val)
        {
            r_ *= val;
            i_ *= val;
            return *this;
        }
        this_type& operator/=(const T& val)
        {
            r_ /= val;
            i_ /= val;
            return *this;
        }
        this_type& operator+=(const this_type& source)
        {
            r_ += source.r_;
            i_ += source.i_;
            return *this;
        }
        this_type& operator-=(const this_type& source)
        {
            r_ -= source.r_;
            i_ -= source.i_;
            return *this;
        }
        this_type& operator*=(const this_type& source)
        {
            *this = *this * source;
            return *this;
        }
        this_type& operator/=(const this_type& source)
        {
            *this = *this / source;
            return *this;
        }
    private:
        T   r_,i_;
};
}
}
#if BOOST_UNITS_HAS_BOOST_TYPEOF
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::complex, 1)
#endif
namespace boost {
namespace units {
template<class X>
complex<typename unary_plus_typeof_helper<X>::type>
operator+(const complex<X>& x)
{
    typedef typename unary_plus_typeof_helper<X>::type  type;
    return complex<type>(x.real(),x.imag());
}
template<class X>
complex<typename unary_minus_typeof_helper<X>::type>
operator-(const complex<X>& x)
{
    typedef typename unary_minus_typeof_helper<X>::type type;
    return complex<type>(-x.real(),-x.imag());
}
template<class X,class Y>
complex<typename add_typeof_helper<X,Y>::type>
operator+(const complex<X>& x,const complex<Y>& y)
{
    typedef typename boost::units::add_typeof_helper<X,Y>::type type;
    return complex<type>(x.real()+y.real(),x.imag()+y.imag());
}
template<class X,class Y>
complex<typename boost::units::subtract_typeof_helper<X,Y>::type>
operator-(const complex<X>& x,const complex<Y>& y)
{
    typedef typename boost::units::subtract_typeof_helper<X,Y>::type    type;
    return complex<type>(x.real()-y.real(),x.imag()-y.imag());
}
template<class X,class Y>
complex<typename boost::units::multiply_typeof_helper<X,Y>::type>
operator*(const complex<X>& x,const complex<Y>& y)
{
    typedef typename boost::units::multiply_typeof_helper<X,Y>::type    type;
    return complex<type>(x.real()*y.real() - x.imag()*y.imag(),
                         x.real()*y.imag() + x.imag()*y.real());
//  fully correct implementation has more complex return type
//
//    typedef typename boost::units::multiply_typeof_helper<X,Y>::type xy_type;
//    
//    typedef typename boost::units::add_typeof_helper<
//      xy_type,xy_type>::type         xy_plus_xy_type;
//    typedef typename
//        boost::units::subtract_typeof_helper<xy_type,xy_type>::type
//        xy_minus_xy_type;
//    
//    BOOST_STATIC_ASSERT((boost::is_same<xy_plus_xy_type,
//                                       xy_minus_xy_type>::value == true));
//    
//    return complex<xy_plus_xy_type>(x.real()*y.real()-x.imag()*y.imag(),
//                                    x.real()*y.imag()+x.imag()*y.real());
}
template<class X,class Y>
complex<typename boost::units::divide_typeof_helper<X,Y>::type>
operator/(const complex<X>& x,const complex<Y>& y)
{
    // naive implementation of complex division
    typedef typename boost::units::divide_typeof_helper<X,Y>::type type;
    return complex<type>((x.real()*y.real()+x.imag()*y.imag())/
                            (y.real()*y.real()+y.imag()*y.imag()),
                         (x.imag()*y.real()-x.real()*y.imag())/
                            (y.real()*y.real()+y.imag()*y.imag()));
//  fully correct implementation has more complex return type
//
//  typedef typename boost::units::multiply_typeof_helper<X,Y>::type xy_type;
//  typedef typename boost::units::multiply_typeof_helper<Y,Y>::type yy_type;
//
//  typedef typename boost::units::add_typeof_helper<xy_type, xy_type>::type
//      xy_plus_xy_type;
//  typedef typename boost::units::subtract_typeof_helper<
//      xy_type,xy_type>::type xy_minus_xy_type;
//
//  typedef typename boost::units::divide_typeof_helper<
//      xy_plus_xy_type,yy_type>::type      xy_plus_xy_over_yy_type;
//  typedef typename boost::units::divide_typeof_helper<
//      xy_minus_xy_type,yy_type>::type     xy_minus_xy_over_yy_type;
//
//  BOOST_STATIC_ASSERT((boost::is_same<xy_plus_xy_over_yy_type,
//                                  xy_minus_xy_over_yy_type>::value == true));
//
//  return complex<xy_plus_xy_over_yy_type>(
//      (x.real()*y.real()+x.imag()*y.imag())/
//          (y.real()*y.real()+y.imag()*y.imag()),
//      (x.imag()*y.real()-x.real()*y.imag())/
//          (y.real()*y.real()+y.imag()*y.imag()));
}
template<class Y>
complex<Y>
pow(const complex<Y>& x,const Y& y)
{
    std::complex<Y> tmp(x.real(),x.imag());
    tmp = std::pow(tmp,y);
    return complex<Y>(tmp.real(),tmp.imag());
}
template<class Y>
std::ostream& operator<<(std::ostream& os,const complex<Y>& val)
{
    os << val.real() << " + " << val.imag() << " i";
    return os;
}
/// specialize power typeof helper for complex<Y>
template<class Y,long N,long D>
struct power_typeof_helper<complex<Y>,static_rational<N,D> >
{
    typedef complex<
        typename power_typeof_helper<Y,static_rational<N,D> >::type
    > type;
    static type value(const complex<Y>& x)
    {
        const static_rational<N,D>  rat;
        const Y    m = Y(rat.numerator())/Y(rat.denominator());
        return boost::units::pow(x,m);
    }
};
/// specialize root typeof helper for complex<Y>
template<class Y,long N,long D>
struct root_typeof_helper<complex<Y>,static_rational<N,D> >
{
    typedef complex<
        typename root_typeof_helper<Y,static_rational<N,D> >::type
    > type;
    static type value(const complex<Y>& x)
    {
        const static_rational<N,D>  rat;
        const Y    m = Y(rat.denominator())/Y(rat.numerator());
        return boost::units::pow(x,m);
    }
};
/// specialize power typeof helper for complex<quantity<Unit,Y> >
template<class Y,class Unit,long N,long D>
struct power_typeof_helper<complex<quantity<Unit,Y> >,static_rational<N,D> >
{
    typedef typename
        power_typeof_helper<Y,static_rational<N,D> >::type       value_type;
    typedef typename
        power_typeof_helper<Unit,static_rational<N,D> >::type    unit_type;
    typedef quantity<unit_type,value_type>                      quantity_type;
    typedef complex<quantity_type>                              type;
    static type value(const complex<quantity<Unit,Y> >& x)
    {
        const complex<value_type>   tmp =
            pow<static_rational<N,D> >(complex<Y>(x.real().value(),
                                                  x.imag().value()));
        return type(quantity_type::from_value(tmp.real()),
                    quantity_type::from_value(tmp.imag()));
    }
};
/// specialize root typeof helper for complex<quantity<Unit,Y> >
template<class Y,class Unit,long N,long D>
struct root_typeof_helper<complex<quantity<Unit,Y> >,static_rational<N,D> >
{
    typedef typename
        root_typeof_helper<Y,static_rational<N,D> >::type       value_type;
    typedef typename
        root_typeof_helper<Unit,static_rational<N,D> >::type    unit_type;
    typedef quantity<unit_type,value_type>                      quantity_type;
    typedef complex<quantity_type>                              type;
    static type value(const complex<quantity<Unit,Y> >& x)
    {
        const complex<value_type>   tmp =
            root<static_rational<N,D> >(complex<Y>(x.real().value(),
                                                   x.imag().value()));
        return type(quantity_type::from_value(tmp.real()),
                   quantity_type::from_value(tmp.imag()));
    }
};
} // namespace units
} // namespace boost

С этим классом замены<complex>мы можем объявить сложную переменную:

typedef quantity<length,complex<double> >     length_dimension;
length_dimension    L(complex<double>(2.0,1.0)*meters);

Чтобы получить правильное поведение для всех случаев, поддерживаемых<quantity>с<complex>типом значения:

+L      = 2 + 1 i m
-L      = -2 + -1 i m
L+L     = 4 + 2 i m
L-L     = 0 + 0 i m
L*L     = 3 + 4 i m^2
L/L     = 1 + 0 i dimensionless
L^3     = 2 + 11 i m^3
L^(3/2) = 2.56713 + 2.14247 i m^(3/2)
3vL     = 1.29207 + 0.201294 i m^(1/3)
(3/2)vL = 1.62894 + 0.520175 i m^(2/3)

и<complex<quantity>типом значения

typedef complex<quantity<length> >     length_dimension;
length_dimension    L(2.0*meters,1.0*meters);

давать

+L      = 2 m + 1 m i
-L      = -2 m + -1 m i
L+L     = 4 m + 2 m i
L-L     = 0 m + 0 m i
L*L     = 3 m^2 + 4 m^2 i
L/L     = 1 dimensionless + 0 dimensionless i
L^3     = 2 m^3 + 11 m^3 i
L^(3/2) = 2.56713 m^(3/2) + 2.14247 m^(3/2) i
3vL     = 1.29207 m^(1/3) + 0.201294 m^(1/3) i
(3/2)vL = 1.62894 m^(2/3) + 0.520175 m^(2/3) i

performance.cpp

Этот пример обеспечивает специальный тест производительности для проверки того, что нулевые накладные расходы на время выполнения возникают при использовании<quantity>вместо<double>. Обратите внимание, что оптимизация производительности и тестирование не тривиальны, поэтому в профилировании необходимо соблюдать определенную осторожность. Также важно иметь компилятор, способный эффективно оптимизировать множество инстанциаций шаблонов и встроенных вызовов для достижения максимальной производительности. Нулевые накладные расходы для этого теста были проверены с использованием gcc 4.0.1 и icc 9.0, 10.0 и 10.1 на Mac OS 10.4 и 10.5 и с использованием msvc 8.0 на Windows XP.

radar_beam_height.cpp

Этот пример демонстрирует реализацию двух не-СИ единиц длины, морской мили:

namespace nautical {
struct length_base_unit :
    boost::units::base_unit<length_base_unit, length_dimension, 1>
{
    static std::string name()       { return "nautical mile"; }
    static std::string symbol()     { return "nmi"; }
};
typedef boost::units::make_system<length_base_unit>::type system;
/// unit typedefs
typedef unit<length_dimension,system>    length;
static const length mile,miles;
} // namespace nautical
// helper for conversions between nautical length and si length
BOOST_UNITS_DEFINE_CONVERSION_FACTOR(nautical::length_base_unit,
                                     boost::units::si::meter_base_unit,
                                     double, 1.852e3);

Имперская нога :

namespace imperial {
struct length_base_unit :
    boost::units::base_unit<length_base_unit, length_dimension, 2>
{
    static std::string name()       { return "foot"; }
    static std::string symbol()     { return "ft"; }
};
typedef boost::units::make_system<length_base_unit>::type system;
/// unit typedefs
typedef unit<length_dimension,system>    length;
static const length foot,feet;
} // imperial
// helper for conversions between imperial length and si length
BOOST_UNITS_DEFINE_CONVERSION_FACTOR(imperial::length_base_unit,
                                     boost::units::si::meter_base_unit,
                                     double, 1.0/3.28083989501312);

Эти единицы включают преобразования между собой и счетчиком. Определены три функции для вычисления высоты радиолокационного луча с радиолокационной дальности и локального радиуса Земли. Первый берет аргументы в одной системе и возвращает значение в той же системе:

template<class System,typename T>
quantity<unit<boost::units::length_dimension,System>,T>
radar_beam_height(const quantity<unit<length_dimension,System>,T>& radar_range,
                  const quantity<unit<length_dimension,System>,T>& earth_radius,
                  T k = 4.0/3.0)
{
    return quantity<unit<length_dimension,System>,T>
        (pow<2>(radar_range)/(2.0*k*earth_radius));
}

Второй тип аналогичен, но шаблонируется по типу возврата, так что аргументы преобразуются в систему возврата внутри:

template<class return_type,class System1,class System2,typename T>
return_type
radar_beam_height(const quantity<unit<length_dimension,System1>,T>& radar_range,
                  const quantity<unit<length_dimension,System2>,T>& earth_radius,
                  T k = 4.0/3.0)
{
    // need to decide which system to use for calculation
    const return_type   rr(radar_range),
                        er(earth_radius);
    return return_type(pow<2>(rr)/(2.0*k*er));
}

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

quantity<imperial::length>
radar_beam_height(const quantity<nautical::length>& range)
{
    return quantity<imperial::length>
        (pow<2>(range/(1.23*nautical::miles/root<2>(imperial::feet))));
}

С их помощью можно вычислить высоту луча радара в различных системах агрегатов:

const quantity<nautical::length> radar_range(300.0*miles);
const quantity<si::length>       earth_radius(6371.0087714*kilo*meters);
const quantity<si::length>       beam_height_1(radar_beam_height(quantity<si::length>(radar_range),earth_radius));
const quantity<nautical::length> beam_height_2(radar_beam_height(radar_range,quantity<nautical::length>(earth_radius)));
const quantity<si::length>       beam_height_3(radar_beam_height< quantity<si::length> >(radar_range,earth_radius));
const quantity<nautical::length> beam_height_4(radar_beam_height< quantity<nautical::length> >(radar_range,earth_radius));

давать

radar range        : 300 nmi
earth radius       : 6.37101e+06 m
beam height 1      : 18169.7 m
beam height 2      : 9.81085 nmi
beam height 3      : 18169.7 m
beam height 4      : 9.81085 nmi
beam height approx : 59488.4 ft
beam height approx : 18132.1 m

heterogeneous_unit.cpp.

Смешанные единицы и смешанные единицы преобразования.

Этот код:

quantity<si::length>        L(1.5*si::meter);
quantity<cgs::mass>         M(1.0*cgs::gram);
std::cout << L << std::endl
          << M << std::endl
          << L*M << std::endl
          << L/M << std::endl
          << std::endl;
std::cout << 1.0*si::meter*si::kilogram/pow<2>(si::second) << std::endl
          << 1.0*si::meter*si::kilogram/pow<2>(si::second)/si::meter
          << std::endl << std::endl;
std::cout << 1.0*cgs::centimeter*si::kilogram/pow<2>(si::second) << std::endl
          << 1.0*cgs::centimeter*si::kilogram/pow<2>(si::second)/si::meter
          << std::endl << std::endl;

давать

1.5 m
1 g
1.5 m g
1.5 m g^-1
1 N
1 kg s^-2
1 cm kg s^-2
1 cm m^-1 kg s^-2

Произвольные преобразования также работают:

quantity<si::area>      A(1.5*si::meter*cgs::centimeter);
std::cout << 1.5*si::meter*cgs::centimeter << std::endl
          << A << std::endl
          << std::endl;

доходность

1.5 cm m
0.015 m^2

Температура. cpp

Этот пример демонстрирует использование абсолютных температур и относительных температурных различий в Фаренгейте и преобразование между ними и температурной шкалой Кельвина. Этот вопрос затрагивает некоторые удивительно глубокие математические понятия (см.Википедиядля базового обзора), но для наших целей здесь мы просто заметим, что важно уметь различать абсолютное измерение температуры и измерение разности температур. Это достигается с помощью.<absolute>Оберточный класс.

Сначала мы определим систему, используя предварительно заданный базовый блок по Фаренгейту:

typedef temperature::fahrenheit_base_unit::unit_type    temperature;
typedef get_system<temperature>::type                   system;
BOOST_UNITS_STATIC_CONSTANT(degree,temperature);
BOOST_UNITS_STATIC_CONSTANT(degrees,temperature);

Теперь мы можем создать несколько величин:

quantity<absolute<fahrenheit::temperature> >    T1p(
    32.0*absolute<fahrenheit::temperature>());
quantity<fahrenheit::temperature>               T1v(
    32.0*fahrenheit::degrees);
quantity<absolute<si::temperature> >            T2p(T1p);
quantity<si::temperature>                       T2v(T1v);

Обратите внимание на использование<absolute>для обертывания устройства. Результатом является:

{ 32 } F
{ 273.15 } K
{ 273.15 } K
[ 32 ] F
[ 17.7778 ] K
[ 17.7778 ] K

runtime_conversion_factor.cpp

Начало. Библиотека единиц не требует, чтобы коэффициенты преобразования составляли постоянные времени, как показано в этом примере:

using boost::units::base_dimension;
using boost::units::base_unit;
static const long currency_base = 1;
struct currency_base_dimension : base_dimension<currency_base_dimension, 1> {};
typedef currency_base_dimension::dimension_type currency_type;
template<long N>
struct currency_base_unit :
    base_unit<currency_base_unit<N>, currency_type, currency_base + N> {};
typedef currency_base_unit<0> us_dollar_base_unit;
typedef currency_base_unit<1> euro_base_unit;
typedef us_dollar_base_unit::unit_type us_dollar;
typedef euro_base_unit::unit_type euro;
// an array of all possible conversions
double conversion_factors[2][2] = {
    {1.0, 1.0},
    {1.0, 1.0}
};
double get_conversion_factor(long from, long to) {
    return(conversion_factors[from][to]);
}
void set_conversion_factor(long from, long to, double value) {
    conversion_factors[from][to] = value;
    conversion_factors[to][from] = 1.0 / value;
}
BOOST_UNITS_DEFINE_CONVERSION_FACTOR_TEMPLATE((long N1)(long N2),
    currency_base_unit<N1>,
    currency_base_unit<N2>,
    double, get_conversion_factor(N1, N2));

non_base_dimension.cpp

Можно также определить базовые единицы, которые получили, а не базовые размеры:

struct imperial_gallon_tag :
    base_unit<imperial_gallon_tag, volume_dimension, 1> { };
typedef make_system<imperial_gallon_tag>::type imperial;
typedef unit<volume_dimension,imperial> imperial_gallon;
struct us_gallon_tag : base_unit<us_gallon_tag, volume_dimension, 2> { };
typedef make_system<us_gallon_tag>::type us;
typedef unit<volume_dimension,us> us_gallon;

composite_output.cpp

Если устройство имеет специальное имя и/или символ, то свободные функции<name_string>и<symbol_string>могут быть перегружены непосредственно.

std::string name_string(const cgs::force&)
{
    return "dyne";
}
std::string symbol_string(const cgs::force&)
{
    return "dyn";
}

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

Специальные названия и символы для систем SI и CGS встречаются в<boost/units/systems/si/io.hpp>и<boost/units/systems/cgs/io.hpp>соответственно. Если эти заголовки не включены, выход будет просто следовать правилам по умолчанию, используя соответствующие фундаментальные размеры. Обратите внимание, что ни одна из этих функций не определена для величин, поскольку для этого потребуется сделать предположения о том, как следует форматировать соответствующий тип значений.

Для удобства предусмотрены три форматтера<ostream>,<symbol_format>,<name_format>и<typename_format>. Они выбирают текстовое представление блоков, предоставленное<symbol_string>или<name_string>в первых двух случаях, в то время как последний возвращает распутанное имя типа для целей отладки. Форматирование масштабируемой единицы также выполняется правильно.

Очень часто бывает так, что требуется.<unit>автоматически, в зависимости от его значения, удерживать составную часть в ограниченном диапазоне, обычно между 1 и 999.

Например, используя префиксытехнических обозначений,

"1234.5 m" is more helpfully displayed as "1.234 km"
"0.000000001234 m" is more clearly displayed as "1.2345 nanometer".

Манипуляторы йострима<engineering_prefixes>или<binary_prefixes>облегчают это.

using boost::units::binary_prefix;
using boost::units::engineering_prefix;
using boost::units::no_prefix;
quantity<length> l = 2.345 * meters;   // A quantity of length, in units of meters.
cout << engineering_prefix << l << endl; // Outputs "2.345 m".
l =  1000.0 * l; // Increase it by 1000, so expect a k prefix.
// Note that a double 1000.0 is required - an integer will fail to compile.
cout << engineering_prefix << l << endl; // Output autoprefixed with k to "2.345 km".
quantity<energy> e = kilograms * pow<2>(l / seconds); // A quantity of energy.
cout << engineering_prefix << e << endl; // 5.49902 MJ
cout << name_format << engineering_prefix << e << endl; // 5.49902 megaJoule

(Полный наборинженерных и научных мультипликаторовне используется (например, не цент или деци), а только мощности десяти, которые кратны трем, 103).

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

Это 2^10 = 1024, 2^20 = 1 048 576, 2^30 ... кратных.

(См. такжеПриставки для двоичных кратных)

Эта шкала указана в IEC 60027-2, Второе издание, 2000-11, Буквенные символы для использования в электротехнике - Часть 2: Телекоммуникации и электроника.

// Don't forget that the units name or symbol format specification is persistent.
cout << symbol_format << endl; // Resets the format to the default symbol format.
quantity<byte_base_unit::unit_type> b = 2048. * byte_base_unit::unit_type();
cout << engineering_prefix << b << endl;  // 2.048 kb
cout << symbol_format << binary_prefix << b << endl; //  "2 Kib"

Но обратите внимание, что скалярные безразмерные значения, такие как int, float и double, являются, а не, автоматически префиксируемыми манипуляторами iostream.

const double s1 = 2345.6;
const long x1 = 23456;
cout << engineering_prefix << s1 << endl; // 2345.6
cout << engineering_prefix << x1 << endl; // 23456
cout << binary_prefix << s1 << endl; // 2345.6
cout << binary_prefix << x1 << endl; // 23456

Вы можете вывести имя или символ единицы (а не наиболее распространенное количество единицы).

const length L; // A unit of length (but not a quantity of length).
cout << L << endl; // Default length unit is meter,
// but default is symbol format so output is just "m".
cout << name_format << L << endl; // default length name is "meter".

Также обратите внимание, что все флаги форматирования являются постоянными, так что если вы установите Engineering_prefix, то это относится ко всем будущим выводам, пока вы не выберете binary_prefix или явно не выключите автопрефикс. Вы можете указать отсутствие префикса (конечно, по умолчанию) двумя способами:

no_prefix(cout); // Clear any prefix flag.
cout << no_prefix << endl; // Clear any prefix flag using `no_prefix` manipulator.

И вы можете получить флаги формата для диагностики проблем.

cout << boost::units::get_autoprefix(cout) << endl; // 8 is `autoprefix_binary` from `enum autoprefix_mode`.
cout << boost::units::get_format(cout) << endl; // 1 is `name_fmt` from `enum format_mode`.

Этот код демонстрирует использование свободной функции<conversion_factor>для определения масштабного коэффициента между двумя единицами.

conversion_factor.cpp

double dyne_to_newton =
    conversion_factor(cgs::dyne,si::newton);
std::cout << dyne_to_newton << std::endl;
double force_over_mass_conversion =
    conversion_factor(si::newton/si::kilogram,cgs::dyne/cgs::gram);
std::cout << force_over_mass_conversion << std::endl;
double momentum_conversion =
    conversion_factor(cgs::momentum(),si::momentum());
std::cout << momentum_conversion << std::endl;
double momentum_over_mass_conversion =
    conversion_factor(si::momentum()/si::mass(),cgs::momentum()/cgs::gram);
std::cout << momentum_over_mass_conversion << std::endl;
double acceleration_conversion =
    conversion_factor(cgs::gal,si::meter_per_second_squared);
std::cout << acceleration_conversion << std::endl;

производить

1e-005
100
1e-005
100
0.01

runtime_unit.cpp

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

namespace {
using namespace boost::units;
using imperial::foot_base_unit;
std::map<std::string, quantity<si::length> > known_units;
}
quantity<si::length> calculate(const quantity<si::length>& t)
{
    return(boost::units::hypot(t, 2.0 * si::meters));
}
int main()
{
    known_units["meter"] = 1.0 * si::meters;
    known_units["centimeter"] = .01 * si::meters;
    known_units["foot"] =
        conversion_factor(foot_base_unit::unit_type(), si::meter) * si::meter;
    std::string output_type("meter");
    std::string input;
    while((std::cout << "> ") && (std::cin >> input))
    {
        if(!input.empty() && input[0] == '#')
        {
            std::getline(std::cin, input);
        }
        else if(input == "exit")
        {
            break;
        }
        else if(input == "help")
        {
            std::cout << "type \"exit\" to exit\n"
                "type \"return 'unit'\" to set the return units\n"
                "type \"'number' 'unit'\" to do a simple calculation"
                << std::endl;
        }
        else if(input == "return")
        {
            if(std::cin >> input)
            {
                if(known_units.find(input) != known_units.end())
                {
                    output_type = input;
                    std::cout << "Done." << std::endl;
                }
                else
                {
                    std::cout << "Unknown unit \"" << input << "\""
                         << std::endl;
                }
            }
            else
            {
                break;
            }
        }
        else
        {
            try
            {
                double value = boost::lexical_cast<double>(input);
                if(std::cin >> input)
                {
                    if(known_units.find(input) != known_units.end())
                    {
                        std::cout << static_cast<double>(
                            calculate(value * known_units[input]) /
                            known_units[output_type])
                            << ' ' << output_type << std::endl;
                    }
                    else
                    {
                        std::cout << "Unknown unit \"" << input << "\""
                            << std::endl;
                    }
                }
                else
                {
                    break;
                }
            }
            catch(...)
            {
                std::cout << "Input error" << std::endl;
            }
        }
    }
}

lambda.cpp

Заголовок<boost/units/lambda.hpp>обеспечивает перегрузки и специализацию, необходимые для создания Boost. Объединяется с Boost. Библиотека Ламбда.

int main(int argc, char **argv) {
   using namespace std;
   namespace bl = boost::lambda;
   namespace bu = boost::units;
   namespace si = boost::units::si;
   ////////////////////////////////////////////////////////////////////////
   // Mechanical example: linear accelerated movement
   ////////////////////////////////////////////////////////////////////////
   // Initial condition variables for acceleration, speed, and displacement
   bu::quantity<si::acceleration> a = 2.0 * si::meters_per_second_squared;
   bu::quantity<si::velocity> v = 1.0 * si::meters_per_second;
   bu::quantity<si::length> s0 = 0.5 * si::meter;
   // Displacement over time
   boost::function<bu::quantity<si::length> (bu::quantity<si::time>) >
       s = 0.5 * bl::var(a) * bl::_1 * bl::_1
           + bl::var(v) * bl::_1
           + bl::var(s0);
   cout << "Linear accelerated movement:" << endl
        << "a = " << a << ", v = " << v << ", s0 = " << s0 << endl
        << "s(1.0 * si::second) = " << s(1.0 * si::second) << endl
        << endl;
   // Change initial conditions
   a = 1.0 * si::meters_per_second_squared;
   v = 2.0 * si::meters_per_second;
   s0 = -1.5 * si::meter;
   cout << "a = " << a << ", v = " << v << ", s0 = " << s0 << endl
        << "s(1.0 * si::second) = " << s(1.0 * si::second) << endl
        << endl;
   ////////////////////////////////////////////////////////////////////////
   // Electrical example: oscillating current
   ////////////////////////////////////////////////////////////////////////
   // Constants for the current amplitude, frequency, and offset current
   const bu::quantity<si::current> iamp = 1.5 * si::ampere;
   const bu::quantity<si::frequency> f = 1.0e3 * si::hertz;
   const bu::quantity<si::current> i0 = 0.5 * si::ampere;
   // The invocation of the sin function needs to be postponed using
   // bind to specify the oscillation function. A lengthy static_cast
   // to the function pointer referencing boost::units::sin() is needed
   // to avoid an "unresolved overloaded function type" error.
   boost::function<bu::quantity<si::current> (bu::quantity<si::time>) >
       i = iamp
           * bl::bind(static_cast<bu::dimensionless_quantity<si::system, double>::type (*)(const bu::quantity<si::plane_angle>&)>(bu::sin),
                      2.0 * pi * si::radian * f * bl::_1)
           + i0;
   cout << "Oscillating current:" << endl
        << "iamp = " << iamp << ", f = " << f << ", i0 = " << i0 << endl
        << "i(1.25e-3 * si::second) = " << i(1.25e-3 * si::second) << endl
        << endl;
   ////////////////////////////////////////////////////////////////////////
   // Geometric example: area calculation for a square
   ////////////////////////////////////////////////////////////////////////
   // Length constant
   const bu::quantity<si::length> l = 1.5 * si::meter;
   // Again an ugly static_cast is needed to bind pow<2> to the first
   // function argument.
   boost::function<bu::quantity<si::area> (bu::quantity<si::length>) >
       A = bl::bind(static_cast<bu::quantity<si::area> (*)(const bu::quantity<si::length>&)>(bu::pow<2>),
                    bl::_1);
   cout << "Area of a square:" << endl
        << "A(" << l <<") = " << A(l) << endl << endl;
   ////////////////////////////////////////////////////////////////////////
   // Thermal example: temperature difference of two absolute temperatures
   ////////////////////////////////////////////////////////////////////////
   // Absolute temperature constants
   const bu::quantity<bu::absolute<si::temperature> >
       Tref = 273.15 * bu::absolute<si::temperature>();
   const bu::quantity<bu::absolute<si::temperature> >
       Tamb = 300.00 * bu::absolute<si::temperature>();
   boost::function<bu::quantity<si::temperature> (bu::quantity<bu::absolute<si::temperature> >,
                                                  bu::quantity<bu::absolute<si::temperature> >)>
       dT = bl::_2 - bl::_1;
   cout << "Temperature difference of two absolute temperatures:" << endl
        << "dT(" << Tref << ", " << Tamb << ") = " << dT(Tref, Tamb) << endl
        << endl;
   return 0;
}


PrevUpHomeNext

Статья Examples раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 40. Boost.Units 1.1.0 может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 40. Boost.Units 1.1.0 ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 17:28:31/0.02147102355957/0