6

情報:

私は現在、テンプレートのメタプログラミングを学ぼうとしています (この本に従って)。彼らが与える有用な例の1つは、次元分析です。本のように実装したところ、すべて問題ありませんでした。ここを参照してください

しかし、私の問題は、次元分析フレームワークを混合型で使用したいということです。これにより、質量の次元を持つスカラーにベクトルに加速度の次元を掛けて、ベクトルの力を与えることができると言うことができます。リンクにあるように、それらTはすべての操作の入力と出力に対して同じタイプでのみ機能します。

スカラーの乗算/除算などに必要なすべての操作を備えた 3-vector クラスがあるので、次のようなことをしたいと思います。

quantity<double,mass> m(1.0);
quantity<vect,acceleration> a(vect(0.0,0.0,-9.81));
quantity<vect,force> f = m*a;

最初の試み:

これを達成するために、本からの例を拡張して、2つの異なる型を入力として処理しようとしましたoperator*operator/、戻り値の型に関しては壁にぶつかりました。

私はここで の戻り値の型が であることを知っていますdouble * vectvect、それらが逆の場合vect * doubleでもvect. 悪い; 原則として、戻り値の型は何でもかまいません。だから私はのoperator*ようなものに拡張する方法が欲しい

template<class T1, class T2, class Dim1, class Dim2>
quantity<X, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2)
{
    return quantity<X,
                    typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
                   (q1.value()*q2.value());
}

whereXは の戻り値の型でq1.value()*q2.value()、コンパイル時に推定されます。T3別のテンプレート クラスを署名に追加して戻そうとしましたが、どうあるべきかをT3推測できないようです。T3

2 回目の試行:

次に次のように使用decltypeしてみました

template<class T1, class T2>
struct return_type
{
    auto mult_f(const T1& a, const T2& b)->decltype(a*b){return a*b;}
    typedef decltype(mult_f) type;
};

template<class T1, class T2, class Dim1, class Dim2>
quantity<typename return_type<T1,T2>::type, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2)
{
    return quantity<typename return_type<T1,T2>::type,
                    typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type>
                   (q1.value()*q2.value());
}

ただし、これにより、多数の理解できないコンパイラ エラーがスローされます。

質問:

私の質問は、正しい方法で使用していますが、どこかdecltypeに指定子などの構文がありませんか? typenameまたは; この方法でこれを行うことさえ可能ですか?そうでない場合、関数の戻り値の型を計算する方法はありますか?

ありがとう。

4

1 に答える 1

6

わかりました、最初にタイプreturn_type<T1,T2>::typeはあなたが期待しているようには見えませんが、メソッドのタイプです。つまり、あなたが期待しているタイプですT3 (return_type::*)(const T1&, const T2&)T3中間クラスを使用する場合は、次を使用できます。

template <typename T1, typename T2>
struct return_type
{
  typedef decltype(std::declval<T1>()*std::declval<T2>()) type;
};

ただしdecltype(T1()*T2())、製品のタイプを取得するために直接使用することもできます。

編集:ildjarnの提案でコードを編集したので、デフォルトで構築可能な型は必要ありません。含めることを忘れないでください<utility>

于 2012-06-19T09:15:31.747 に答える