我會反對這個設計。
違反最少驚喜的原則:你的圖像類是元素類型不可知的,但迭代器不是。
使用不同的選項,所有的缺點:
1.使圖像類本身就是一個模板
...並提供轉讓/他們
template <typename TElement> class Image
{
public:
...
template <typename TOtherElement>
Image(Image<TotherElement const & rhs);
...
};
這之間的轉換將if (image.is(...))
上移一級。不一定更好,但不太令人驚訝(以一種好的方式)。
您可以實現對所有這些的頂部圖像處理共享接口:
class IImageManipulation
{
public:
virtual void FlipH() = 0;
virtual void FlipV() = 0;
virtual void Rotate(float angleDegrees) = 0;
...
virtual void ~IImageManipulation() {}
};
template <typename TElement>
class Image : public IImageManipulation
{
// ... also implement the abstract methods
}
[編輯]重新「
我不能讓這個模板圖像類,因爲我需要導入圖像在任何深度的文件和任意數量的像素」:
unique_ptr<IImageManipulation> LoadImage(....)
{
// inspect stream what depth and pixel format you use
..
// create instance
unique_ptr<IImageManipulation> img = CreateImage(pixeltype);
// ... and load
img->Load(file);
}
// Image factory function:
unique_ptr<IImgManipulation> CreateImage(PixelType type)
{
switch (pixeltype)
{
case ptFloat: return unique_ptr<IImageManipulation>(new Image<float>());
...
}
}
您的容器將存儲unique_ptr<IImageManipulation>
。
這個想法是將所有通用圖像操作移動到界面。 這是而不是適用於像素級別的操作,需要在Image
模板中實現或使用該模板。但是,對於圖像級別的操作,這是很好的。
2.進行迭代器類型不可知
即迭代未模板化,但在一個「像素」類型,它可以處理所有不同的像素格式進行迭代。
理想的情況下,迭代器將實現像素格式轉換:
Image imgf = MakeImage<float>(...); // an image storing floats
for(Image::iterator it = imgf.begin(); ...)
{
Pixel & p = *it; // type of the iterator elements
float f = p.asFloat(); // read as float
int i = p.asInt32(); // read as int, convert in the fly
p = Pixel.FromRGB(17, 23, 432); // set as int, convert on the fly
p = Pixel.FromFloat(0.23);
}
請注意,轉換可製成隱含的,但如果你有不同的像素格式,具有不同的基本類型,這可能是一個問題(例如,32 bit RGBA vs. ABGR)
在內部循環中進行這種轉換效率可能不是微不足道的。
無法使用圖像類包含模板參數及其迭代器的類型和類型嗎?例如'圖片 :: iterator' –
@ W.F。你的意思是typedef?但是,無論如何,我怎樣才能做到這一點? – manatttta