2016-03-23 16 views
2

私は、size_tテンプレートパラメータにアクセスするための最良の方法は何か、私は別のテンプレートベースのクラスに渡すことができます(メソッド呼び出しではないので)。私はクラスを持っている場合たとえば、size_tテンプレートパラメータの抽出

template<typename T, size_t D> class Point; 
template<typename T> class Line; 

template<typename T, size_t D> 
class Shape 
{ 
    public: 
    virtual size_t dims() const = 0; 
    virtual bool intersects(Point<T,D> p) const = 0; 
    virtual bool intersects(Line<Point<T,D>> l) const = 0; 
} 

template<typename T, size_t D> 
class Point : Shape<T,D> 
{ 
    public: 
    typedef T type; 
    size_t dims() const {return D;} 
    type val(size_t d) {return vals[d];} 
    bool intersects(Point<T,D> p) 
    { 
    for(size_t d=0; d<D; ++d) if(p.vals[d] != vals[d]) return false; 
    return true; 
    }  

    bool intersects(Line<Point<T,D>> l) 
    { 
    return l.intersects(*this); 
    } 

    protected: 
    type vals[D]; 
}; 

// How do I get D??? 
template<typename Point_t> 
class Line : public Shape<typename Point_t::type,??> 
{ 
    public: 
    typedef typename Point_t::type type; 
    size_t dims() const {return point.dims();} 

    bool intersects(Point<type,??> p) {/*stuff*/}  
    bool intersects(Line<Point_t> l) {/*stuff*/} 

    private: 
    Point_t point; 
    type slope; 
}; 

は私がライン内で交差法は、同じ次元(2Dポイントと交差する3Dラインを防ぐ)のポイントを交差するラインのために働くようにしたいです。私はLineがPointと同じパラメータを取ることを考えましたが、コンパイラはデカルト定義のLineとSpherically defined Pointを交差させるなどのエラーをキャッチしませんでした(両方ともPoint<double,3>です)。上の方法で、この問題を避けるために、デカルトと球のクラスを定義できます。

template<typename T, size_t D> class Cartesian : public Point<T,D>{/*stuff*/} 
template<typename T> class Spherical : public Point<T,3> {/*stuff*/} 

Line<Cartesian<double,3>> Line; 
Cartesian<double,3> C3Point; 
Cartesian<double,2> C2Point; 
Spherical<double> SPoint; 
Line.intersects(C3Point); // ok 
Line.intersects(C2Point); // compiler error 
Line.intersects(SPoint); // compiler error 

編集: 私は現在やるが、C++ 11では

Line<Cartesian<double,3>,3> Line; 

答えて

2

...動作しますが、冗長な情報が含まれてい

template<typename Point_t, size_t D> 
class Line : public Shape<typename Point_t::type,D> 
{/*stuff*/} 

としてラインクラスを定義しているものを、あなたは回るかもしれない

size_t dims() const {return D;} 

static constexpr size_t dims() {return D;} 

そしてそう

template<typename Point_t> 
class Line : public Shape<typename Point_t::type, Point_t::dims()> {..}; 
+0

2番目はOPの例を処理しません。 –

+0

@ T.C .:ちょうどそれを見た。 – Jarod42

+0

'Point_t :: type'の前に' typename'は必要ありませんか? –

0

NTO私はそれを考え出したと思います。私の実際のコードは例よりも複雑です(これが解決策を見るのがもっと難しいと思う理由です)。しかし、この基本的な方法はうまくいきました。私は基本的に、私は形になる点を考慮していない、以下のように予想通り

template<typename T> class Line; 

template<typename T, size_t D> 
class Point 
{ 
    public: 
    typedef T type; 
    size_t dims() const {return D;} 
    type val(size_t d) {return vals[d];} 
    bool intersects(Point<T,D> p) 
    { 
    for(size_t d=0; d<D; ++d) if(p.vals[d] != vals[d]) return false; 
    return true; 
    }  

    bool intersects(Line<Point<T,D>> l) 
    { 
    return l.intersects(*this); 
    } 

    protected: 
    type vals[D]; 
}; 

template<typename T> 
class Shape 
{ 
    public: 
    typedef T Point_t; 
    virtual size_t dims() const = 0; 
    virtual bool intersects(Point_t p) const = 0; 
    virtual bool intersects(Line<Point_t> l) const = 0; 
} 

template<typename Point_t> 
class Line : public Shape<Point_t> 
{ 
    public: 
    typedef typename Point_t::type type; 
    size_t dims() const {return point.dims();} 

    bool intersects(Point_t p) {/*stuff*/}  
    bool intersects(Line<Point_t> l) {/*stuff*/} 

    private: 
    Point_t point; 
    type slope; 
}; 

さて、次の作品、

template<typename T, size_t D> class Cartesian : public Point<T,D>{/*stuff*/} 
typedef Cartesian<double,3> Cartesian3D; 
typedef Cartesian<double,2> Cartesian2D; 
template<typename T> class Spherical : public Point<T,3> {/*stuff*/} 

Line<Cartesian3D> Line; 
Cartesian3D CPoint3D; 
Cartesian2D CPoint2D; 
Spherical<double> SPoint; 
Line.intersects(C3Point); // ok 
Line.intersects(C2Point); // compiler error 
Line.intersects(SPoint); // compiler error 

を私のクラスを再構築しました。私がそうするならば、私はDを知るためにShapeクラスを必要とせず、Shapeから派生したものはどれも、次元を得るPoint_tを含みます。 Shapeから派生した各クラスの交差メソッドをPointクラスに明示的に配置することを忘れないでください。

関連する問題