ベクトルに親*オブジェクトの束を格納できることはわかっています。ただし、オブジェクトを呼び出す必要がある関数を親クラスで定義できない場合(サブクラスのテンプレートパラメータに依存します)、コンテナからオブジェクトをどのように取得する必要がありますか?この例ではベクトルから派生クラスオブジェクトを取得する<Parent*>
:
#include <iostream>
class ImageBase{};
template <typename TPixel>
class Image : public ImageBase
{
public:
TPixel GetPixel() const {TPixel a; return a;}
};
template<typename TImage>
void Output(const TImage* image)
{
std::cout << image->GetPixel();
}
int main(int, char *[])
{
// Works correctly
{
Image<float>* image = new Image<float>;
image->GetPixel();
Output(image);
}
{
ImageBase* image = new Image<float>;
Output(image);
}
return 0;
}
出力(画像)。ここで、 'image'はImageBase *であり、GetPixelはImageBaseで定義されていないため失敗します。 dynamic_cast <>サブクラスがいずれかのサブクラスと一致するかどうかを調べるには、たくさんのタイプに分かれていますが、このリストは非常に迅速に長くなる可能性があります。長いリストは1つの場所に置くことができればうまくいくだろうが、これを行うにはどうすればよいだろうか?この関数はImageBase *を取りますが、それは何を返しますか?
returnType? GetSubclass(ImageBase* input)
{
if(dynamic_cast<Image<float>*>(input))
{
return Image<float>*;
}
else if(dynamic_cast<Image<int>*>(input))
{
return Image<int>*;
}
}
それだけで(この例では、セットアップなど)そのテンプレートパラメータによって署名が異なるサブクラスにいくつかのテンプレート関数を呼び出すことができるようにしたいために私には合理的なようで、それをしないのですか?
私の実際のケースでは、ImageとImageBaseの両方がライブラリの一部であるため、それらを変更することはできません。
訪問者のデザインパターンをチェックすると、ダブルディスパッチを実装できます。 – P3trus
おそらく 'any_cast'関数としてBoost.anyを試してみてください。 –
Kerrek SB - any_castの場合、すでにタイプを知る必要がありますか? std :: vector v; v.push_back(新しいint); int * any_cast (v [0]); –