2

私は、高性能計算を達成することを目的とした数値 C++ ライブラリを構築しています (もちろん、double 型が主要な算術型になります)。したがって、私はテンプレート メタプログラミングを多用しています。何を構築したいのか、いつ「問題」が発生したのかを説明するのは読みにくいので、やりたいことを「シミュレート」するおもちゃの例を作成しました。

コンテナーを受け取り、その内容をいくつかの定数に対してスケーリングし、スケーリングされた数値の合計を返すメソッドを設計したいと考えています。簡単にするために、サイズ 3 のコンテナーで動作するようにしたいとします。定数はさまざまであるため、プログラミング時にプログラマー (lib のユーザー) がそれらを提供する必要があります。問題は、これらの定数が単精度または倍精度であり、テンプレート引数として使用できることです。

ただし、一方で、定数をハードコーディングしたかのようにコンパイラーにコードを発行させたいと考えています。

次のコードを検討してください。

#include <iostream>
#include <vector>

#include <boost/array.hpp>

using namespace std;

template<class T, class Coefs>
struct scale_add{

    Coefs coefs;    

    template <class Iterator>
    T apply(Iterator it){
       return coefs[0] * (*(it)) + coefs[1] * (*(it + 1)) + coefs[2] * (*(it + 2));
    }
};

template <class T>
struct my_coefs : public boost::array<T, 3>{
    my_coefs() {
        (*this)[0] = static_cast<T>(3.0);
        (*this)[1] = static_cast<T>(2.7);
        (*this)[2] = static_cast<T>(4.78);
    }
};

int main(){

    vector<double> my_vec(3, 9.1) ;
    typedef scale_add<double,  my_coefs<double> > my_scale_add;
    my_scale_add msa;
    double result = msa.apply(my_vec.begin() );
    cout << result << endl;
    return 0;
    }

ご覧のとおり、プログラマーは my_scale_add のような型を作成できます! これは私が今のところ持っている設計ソリューションです。数値を返す関数 value() を使用して、「フロート」を構造体として表現しようとしました。

struct a1{
    typedef double type;
    static double value(){
        return 0.5;
    }
};

このようにして、タイプをタイプリストなどに入れます。これに関する唯一の問題は、混乱する可能性があり、タイプの再定義などに直面する可能性があることです。しかし、 cout << a1::value() * 4.0 << のようなものを書くとエンドル; コンパイラはそれをインライン化します(私が持っているいくつかの参照によると)。

だから私の質問は、タイプリストなどへのタイプパッキングによる巨大なプログラミングオーバーヘッドなしに、どうすれば2番目の方法( a1::value() )の動作を得ることができるでしょうか? 最初のコードを表現するためのより効率的な方法を提案できますか (わかりました、これは悪い質問と見なすことができます)。結論として、質問がスタックオーバーフローに適合するかどうかはわかりません。また、私はC ++を初めて使用し、ヘッダーファイルからテンプレートメタプログラミングにジャンプする必要があったため、途中でいくつかの情報を見落とした可能性があります、つまり、些細なことを尋ねている可能性があります。前もって感謝します !

4

1 に答える 1

0

私はあなたが何を意味するのか完全には理解していませんが、次のコードがあなたの要件に合うかもしれないと思います。

template<typename Container>
struct scale_add
{
     typedef typename Container::traits_type type;

     Container Impl ;
     template<typename Iterator>
     type apply( Iterator First ) {
          return std::inner_product( std::begin(Impl) , std::end(Impl) ,
                                     First , type(0) );
     }
};

template<typename K>
struct my_scale_add : public std::array<K , 3>
{
     typedef K traits_type ;

     my_scale_add() { 
          (*this)[0] = static_cast<K>( 1.0 );
          (*this)[1] = static_cast<K>( 2.0 );
          (*this)[2] = static_cast<K>( 3.0 );
     }
};

int main()
{
      std::vector<double> my_vec(3,9.1);
      scale_add<my_scale_add<double>> mObject ;

      std::cout << mObject.apply( std::begin(my_vec) ) << std::endl;

      return 0;
}
于 2012-09-19T05:29:14.447 に答える