0

boost::mpl::* で遊んでいる瞬間を追加し、物理ユニットの例を拡張してみます。現時点では、次のコードがあります。

mpl::vector で表される単純な物理ベース ディメンション:

template < int Mass, int Length, int Time, int Temperature, int Angle, int Current >
    struct base_dimension
    {
        typedef typename mpl::vector_c< int, Mass, Length, Time, Temperature, Angle, Current >::type type;
    };

スカラー ベクトル:

typedef base_dimension< 0, 0, 0, 0, 0, 0 >::type base_dimensionless_helper;

base_dimension タイプを格納する単純なタイプ:

template< class base_dimension >
    struct Dimension
    {
        typedef Dimension< base_dimension > type;
        typedef base_dimension              base_dim_type;
    };

スカラー次元:

typedef Dimension< base_dimensionless_helper > base_dimensionless;

簡単なヘルパー:

template < class D1, int fac >
    struct mul_base_dim_fac_typeof
    {
        typedef typename base_dimension< fac, fac, fac, fac, fac, fac >::type fac_vec;
        typedef typename Detail::multiply_typeof_helper< typename D1, fac_vec >::type type;
    };


template < class Dim1, class Dim2 >
    struct add_dim_typeof_helper
    {
        typedef typename add_base_dim_typeof_helper< typename Dim1::base_dim_type, typename Dim2::base_dim_type >::type dim;

        typedef Dimension< dim > type;
    };

最後に派生ディメンションです。使用される式は次のとおりです: (D0 * E0) + (D1 * E1) +...+ (D5 * E5) ... ::type

template < class D0 = base_dimensionless, int E0 = 0,
       class D1 = base_dimensionless, int E1 = 0,
       class D2 = base_dimensionless, int E2 = 0,
       class D3 = base_dimensionless, int E3 = 0,
       class D4 = base_dimensionless, int E4 = 0,
       class D5 = base_dimensionless, int E5 = 0 >
struct derived_dimension
{
    typedef Dimension< typename mul_base_dim_fac_typeof< typename D0::base_dim_type, E0 >::type > d0_type;
    typedef Dimension< typename mul_base_dim_fac_typeof< typename D1::base_dim_type, E1 >::type > d1_type;
    typedef Dimension< typename mul_base_dim_fac_typeof< typename D2::base_dim_type, E2 >::type > d2_type;
    typedef Dimension< typename mul_base_dim_fac_typeof< typename D3::base_dim_type, E3 >::type > d3_type;
    typedef Dimension< typename mul_base_dim_fac_typeof< typename D4::base_dim_type, E4 >::type > d4_type;
    typedef Dimension< typename mul_base_dim_fac_typeof< typename D5::base_dim_type, E5 >::type > d5_type;

    typedef typename Detail::add_dim_typeof_helper< d0_type, d1_type >::type d0_d1_type;
    typedef typename Detail::add_dim_typeof_helper< d0_d1_type, d2_type >::type d0_d1_d2_type;
    typedef typename Detail::add_dim_typeof_helper< d0_d1_d2_type, d3_type >::type d0_d1_d2_d3_type;
    typedef typename Detail::add_dim_typeof_helper< d0_d1_d2_d3_type, d4_type >::type d0_d1_d2_d3_d4_type;
    typedef typename Detail::add_dim_typeof_helper< d0_d1_d2_d3_d4_type, d5_type >::type type;
};

これは期待どおりに機能します。しかし、派生次元の計算を美しくしたいのは、これらの中間の typedef がすべて醜いからです。私の最初のアイデアは、入力ベクトルを 1 つのベクトル (-> ベクトルのベクトル) にプッシュし、それらを 1 つの素敵な for_each ループ内で乗算することでしたが、今まで成功していませんでした。だから私の質問は:

計算を美しくする方法のヒントはありますか?

4

1 に答える 1

0

乗算を明確にするために、ヘルパー関数を定義することから始めることができます。

template < typename D, int E >
struct multiply
{
    typedef Dimension< typename 
        mul_base_dim_fac_typeof< typename 
            D::base_dim_type, 
            E
        >::type
    > type;
};

transformandなどのアルゴリズムを使用することもできますfold(まあ、あなたはむしろ必要ですがreduce、MPLでは提供されていません):

template < class D0 = base_dimensionless, int E0 = 0,
           class D1 = base_dimensionless, int E1 = 0,
           class D2 = base_dimensionless, int E2 = 0,
           class D3 = base_dimensionless, int E3 = 0,
           class D4 = base_dimensionless, int E4 = 0,
           class D5 = base_dimensionless, int E5 = 0 >
struct derived_dimension
{
    typedef mpl::vector<
        mpl::pair< D0, E0 >, mpl::pair< D1, E1 >,
        mpl::pair< D2, E2 >, mpl::pair< D3, E3 >,
        mpl::pair< D4, E4 >, mpl::pair< D5, E5 >
    > pairs;

    typedef typename
        mpl::transform< 
            pairs, 
            multiply< mpl::first< mpl::_1 >, mpl::second< mpl::_1 >;
        >::type products;

    typedef typename
        mpl::fold<
            products,
            base_dimensionless,
            add_dim_typeof_helper< mpl::_, mpl::_ >
        >::type type;
};

免責事項:私はこのコードをまったくテストしていません。その目的は、MPLで何ができるかを理解することだけです。

または、おそらくBoost.Preprocessorを使用して、プリプロセッサを使用して連続したtypedefを生成することもできます。

于 2013-02-21T11:58:11.070 に答える