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);
}

但是现在我想用 boost::array 元素为前 2 个参数调用它(与括号val() 相同),如果 std::vector 和 boost::array 是自我实现的,我将能够从一个公共基类(类接口)强制执行运算符 [] 的实现,因为两者都是库提供的,有没有办法强制/指定这样的限制?

我总是可以使用普通的 c 数组,但它不是很整洁。

编辑:FWIW,这是原始的括号实现:

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

这适用于 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);
    }    
}

如果您设想第二个向量可能与第一个向量的类型不同(例如,第一个向量和第二个 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 回答
1

虽然这对于您的特定问题可能是多余的,但通常您可以通过显式检查是否提供了某些成员以及某些表达式是否有效来检查模板参数是否实现了某个接口。
Boosts概念检查库为您提供了一种干净的方法来做到这一点,但它提供的容器检查类在这里对您没有帮助,因为 Boost.Array 仅支持序列要求的某个子集。

但是,如果您需要一种干净的方式来设置限制,您可以做的是自己建模需求,或者使用 Boosts 实用程序或类似的自定义方法。

于 2010-02-10T14:40:03.087 回答
0

没有办法对模板参数进行类型限制。您可以定义自己的接口并为您想要支持的所有类型创建适配器。

于 2010-02-10T13:37:00.917 回答