2010-11-20 16 views
4

答えは "あなたはテンプレートを使うことができず、仮想関数(動的多形性)を使わなければなりません"と確信していますが、たくさんのコードを複製しなければならないようですもし私がその道を行くなら。ここに設定があります:"実行時のテンプレート"

私は現在2つのクラス、ColorImageSegmentationとGrayscaleImageSegmentationを持っています。彼らは基本的に同じことをしますが、3つの違いがあります - それらは異なるタイプ(ColorImageとGrayscaleImage)で動作します - ヒストグラムの次元数(3対1)が異なります - PixelDifference関数はイメージタイプ

私はクラス

template <TImageType> 
class ImageSegmentation 
{ 
}; 

を作成した場合、私は良い形になります。しかし、私は別のクラスの一員として、このオブジェクトがしたい:

class MyMainClass 
{ 
ImageSegmentation MyImageSegmentation; 
}; 

をしかし、ユーザは、グレースケール画像を開いた場合、私はMyImageSegmentation<GrayScaleType>をインスタンス化したい(MyImageSegmentationのタイプを決定する必要がある。同様のため。派生クラスでは、カラー画像、MyImageSegmentation<ColorType>

、私はポインタを格納してから行うことができます:。

class MyMainClass 
{ 
ImageSegmentation* MyImageSegmentation; 
}; 

... user does something... 
MyImageSegmentation = new ColorImageSegmentation; 

が、どのように私はテンプレートを使用して、このような何かをしますか?問題は、私はたくさんの持っている:起こって物事の

typedef TImageType::HistogramType HistogramType; 
typedef TImageType::PixelType PixelType; 

ソートを、ので、私は、コードの全体の束を複製することなく、動的な多型モデルに変換する方法を知りません。

お散歩に申し訳ありません...誰にも私の提案はありますか?

おかげで、

デビッド

+0

質問を編集して、コードサンプルを適切にフォーマットしてください。 – chris

+0

BoostのGIL(http://www.boost.org/doc/libs/1_45_0/libs/gil/doc/index.html)も同じことをしています。あなたはその問題をどのように解決したのかを確認することができます。 – liori

答えて

5

たぶん、あなたはについての私達に語っていない追加の要件がありますが、あなたがこれまで持っているものから、あなたが含まれているクラスを下型を渡すことができます。

template<typename TImage> 
class MyMainClass 
{ 
    ImageSegmentation<TImage> MyImageSegmentation; 
}; 

あなただけの抽象化の最高レベルで、動的ディスパッチのいくつかの層が必要になりますほとんどの場合:

struct IMainClass 
{ 
    virtual bool SaveToFile(std::string filename) = 0; 
    virtual bool ApplySharpenFilter(int level) = 0; 
    ... 
}; 

template<typename TImage> 
class MyMainClass : public IMainClass 
{ 
    ImageSegmentation<TImage> MyImageSegmentation; 
public: 
    virtual bool SaveToFile(std::string filename); 
    virtual bool ApplySharpenFilter(int level); 
}; 

IMainClass* pMain = new MyMainClass<GrayscaleImage>(); 
+0

+1:共通の基底クラスを作成し、それをテンプレートクラスで派生させます。 – Puppy

+0

IMainClassに何かを保持させることさえできますか?それは単に空にすることができ、実際のテンプレートクラスはそれから派生することができます。これにより、IMainClass * pMain = new MyMainClass ();が可能になります。 これはまさに私が探していたものです。右? –

+0

それは何も "保持"しません。これは、現在の画像を追跡するためのUI(または画像を制御するもの)の抽象的な画像タイプに依存しないインタフェースです。結局のところ、あなたの "Sharpen"メニュー項目(これがPhotoshopクローンの場合)は、アクティブなファイルに影響を与えなければならず、無数のファイルタイプに対してそうする必要があります。 –

1

テンプレート化バージョンのオブジェクトを作成したいが、それらのオブジェクトはテンプレート化パラメータに基づいて異なるパラメータタイプを使用しますか?これはライブラリに統合するのは簡単ではありませんが、いくつかの方法があります。

インスピレーションのためにunary_functionを見てください。そこでは、魔法の任意の並べ替えを動作させることなく、型パラメータ持ち歩くテンプレートの特性を使用している:

template <class Arg, class Result> 
    struct unary_function { 
    typedef Arg argument_type; 
    typedef Result result_type; 
    }; 

「unary_function」のtypedefを宣言する以外の機能は含まれていません。ただし、これらのtypedefを使用すると、コードで表現したり、コンパイル時にコードセグメント間の同等の名前を付けることができます。テンプレートパラメータのチェック方法を活用します。

template<typename T> 
struct Foo{ 
    typedef typename T::argument_type argument_type; 
    Foo(T _myFunc) : m_Func(_myFunc) 
    void myWrappedFunction(argument_type _argument){ m_Func(_argument); } 
}; 

事前にそれらを指定しなくても、その中に、引数の値の型が含まれています。これが何を意味するのか

は、あなたがこの上で動作するオブジェクトを持つことができるということです。したがって、画像オブジェクトごとにpixel_typeなどがある場合は、typename T::pixel_typeというだけで、必要な型パラメータが呼び出されます。

+0

小麦、返事のおかげで。私はこれがTが実行時に設定されることができる方法を参照してくださいか?実際には、私が使っているライブラリはすでにこれをしています。T :: argument_typeのようなものが正しい型になるように、実行時にTを指定する必要があります。 –