3

私は次のものを持っています:

template<typename T> class CVector3
{
    CVector3<T> &normalize();
    // more stuff
};

typedef CVector3<float> Vector3f;
typedef CVector3<double> Vector3d;

基本的に、T=float の場合は構造体 Point3f を返し、T=double の場合は構造体 Point3d を返す toPoint() メソッドを追加したいと考えています。2 つの typedef を次のように置き換えてみました。

class Vector3f: public CVector3<float>
{
    Point3f toPoint() const;
};

class Vector3d: public CVector3<double>
{
    Point3d toPoint() const;
};

ただし、normalize() が壊れているため、これは機能しません。Vector3f を返すのではなく、Vector3f と互換性のない CVector3<float> を返します。これは、実際には基本クラスであるためです。基本クラスに normalize() およびその他の public メソッドのラッパー メソッドを追加することもできますが、これらのクラスを維持するのが面倒になるため、これは行いたくありません。

また、typedef を元に戻し、テンプレート定義の外側に追加しようとしました。

template<>
Point3f CVector3<float>::toPoint() const;

template<>
Point3d CVector3<double>::toPoint() const;

テンプレート定義内で toPoint() が宣言されていないため、これはコンパイルされません。戻り型 Point3f/Point3d のため、中に入れることはできません。

どうすればいいですか?どんな助けでも大歓迎です!

4

4 に答える 4

0

クライアントの構文を改善し、特殊化を使用してクライアントがテンプレート引数を間違って取得しないように制約を適用できます。

struct Point3f { float x, y, z; };
struct Point3d { double x, y, z; };

// Base template toPoint returns Point3f.
template<typename T, typename U = Point3f>
class Vector3
{
public:
   Vector3& normalize(){ return Vector3(); }
   U toPoint(){ return Point3f(); }
};

// Specialization for double, toPoint returns Point3d.
template<>
class Vector3<double>
{
public:
   Vector3& normalize(){ return Vector3(); }
   Point3d toPoint(){ return Point3d(); }
};


TEST(TemplateTests2, Test3)
{
   Vector3<float> v1;
   Point3f p1 = v1.toPoint();

   Vector3<double> v2;
   Point3d p2 = v2.toPoint();
}
于 2013-07-12T16:34:01.607 に答える