2

例:

ベクトルで動作する関数があります:

double interpolate2d(const vector<double> & xvals, const vector<double> & yvals, double xv, double yv, const vector<vector<double> > &fvals) {
    int xhi, xlo, yhi, ylo;
    double xphi, yphi;
    bracketval(xvals,xv,xhi,xlo,xphi);
    bracketval(yvals,yv,yhi,ylo,yphi);
    return (fvals[xhi][yhi]*xphi+fvals[xlo][yhi]*(1.-xphi))*yphi + (fvals[xhi][ylo]*xphi+fvals[xlo][ylo]*(1.-xphi))*(1.-yphi);
}

しかし、最初の 2 つの引数 (bracketval() と同じ) の boost::array 要素を使用して呼び出したいと思います。 std::vector と boost::array が自己実装されている場合、両方をoperator[] の実装を強制する一般的な基本クラス (インターフェイスのようなもの) は、どちらもライブラリ提供であるため、そのような制限をキャスト/指定する方法はありますか?

私はいつでも単純な c-array に頼ることができますが、あまりきれいではありません。

編集:FWIW、元のbracketvalの実装は次のとおりです。

void bracketval(const vector<double> &vals, double v, int &hi, int &lo, double &prophi){
    hi=vals.size()-1;
    lo=0;
    while(abs(hi-lo)>1) {
        int md = (hi+lo)/2;
        if(vals[md]>v) hi=md; else lo=md;
    }
    if(vals[hi]!=vals[lo])
        prophi = (v-vals[lo])/(vals[hi]-vals[lo]);
    else
        prophi = 0.5;

}
4

3 に答える 3

1

これはおそらく特定の問題ではやり過ぎですが、一般に、特定のメンバーが提供されているかどうか、およびいくつかの式が有効であるかどうかを明示的に確認することにより、テンプレートパラメーターが特定のインターフェースを実装しているかどうかを確認できます。
Boostsコンセプト チェック ライブラリはそれを行うためのクリーンな方法を提供しますが、Boost.Array はシーケンス要件の特定のサブセットのみをサポートするため、それが提供するコンテナー チェック クラスはここでは役に立ちません。

ただし、制限を明確に設定する方法が必要な場合にできることは、Boosts ユーティリティまたは同様のカスタム アプローチを利用して、要件を自分でモデル化することです。

于 2010-02-10T14:40:03.087 に答える
1

これは、std::vector、boost::array、組み込み配列、および一般にインデックス可能なものすべてで機能します。bracketvalまた、関数をどのように実装する必要があるかについての提案も含めました。

template<class Vec>
void bracketval(Vec const & xvals, double xv, int xhi, int xlo, double xphi)
{
}

template <class Vec, class VecOfVecs>
double interpolate2d(Vec const & xvals, Vec const & yvals, 
                     double xv, double yv,
                     VecOfVecs const & fvals)
{
    int xhi, xlo, yhi, ylo;
    double xphi, yphi;
    bracketval(xvals,xv,xhi,xlo,xphi);
    bracketval(yvals,yv,yhi,ylo,yphi);
    return (fvals[xhi][yhi]*xphi+fvals[xlo][yhi]*(1.-xphi))
             *yphi + (fvals[xhi][ylo]*xphi+fvals[xlo][ylo]
             *(1.-xphi))*(1.-yphi);
}

int main()
{
    {
        std::vector<double> v, w;
        std::vector<std::vector<double> > vv;
        interpolate2d(v, w, 1., 2., vv);
    }
    {
        boost::array<double, 4> v, w;
        boost::array<boost::array<double, 4>, 4> vv;
        interpolate2d(v, w, 1., 2., vv);
    }
    {
        double v[4], w[4];
        double vv[4][4];
        interpolate2d(v, w, 1., 2., vv);
    }    
}

2 番目のベクターが最初のベクターとは異なるタイプになる可能性があると予想される場合は、追加のテンプレート パラメーターを追加することもできます (たとえば、最初のベクターはベクターで、2 番目のベクターは boost::array です)。

template <class VecX, class VecY, class VecOfVecs>
double interpolate2d(VecX const & xvals, VecY const & yvals, 
                     double xv, double yv,
                     VecOfVecs const & fvals)
于 2010-02-10T14:37:22.340 に答える
0

テンプレート パラメーターに型制限を設定する方法はありません。できることは、独自のインターフェイスを定義し、サポートするすべてのタイプのアダプターを作成することです。

于 2010-02-10T13:37:00.917 に答える