runtime patterns

I am sure that the answer is: β€œyou cannot use templates, you need to use virtual functions (dynamic polymorphism)”, but it looks like I would have to duplicate a lot of code if I went along this route, Here is the setting:

I currently have two classes: ColorImageSegmentation and GrayscaleImageSegmentation. They do essentially the same thing, but there are three differences - they work on different types (ColorImage and GrayscaleImage) - parameter, histogram dimension (3 vs 1) is different - PixelDifference function is different depending on the type of image

If I create a class

template <TImageType> class ImageSegmentation { }; 

I would be in good shape. However, I want this object to be a member of another class:

 class MyMainClass { ImageSegmentation MyImageSegmentation; }; 

But the user needs to determine the type MyImageSegmentation (if the user opens the image in grayscale, I want to create an instance of MyImageSegmentation<GrayScaleType> . Similarly for the color image MyImageSegmentation<ColorType> .)

With derived classes, I could save the pointer and then do:

 class MyMainClass { ImageSegmentation* MyImageSegmentation; }; ... user does something... MyImageSegmentation = new ColorImageSegmentation; 

but how do I do something like this using templates? The problem is that I have a lot:

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

something is happening, so I don’t know how to convert them into a dynamic polymorphic model without duplicating a whole bunch of code.

Sorry for the rambling ... does anyone have any suggestions for me?

Thanks,

David

+4
source share
2 answers

Perhaps there are additional requirements that you did not tell us about, but from what you have, you can pass the type down through the containing class:

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

Most likely, you will need some layer of dynamic dispatch, but only at the highest level of abstraction:

 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>(); 
+5
source

Do you want to create a template version of your objects, but do these objects have different types of parameters based on a template parameter? This is not a very simple thing to integrate into the library, but there are several ways to get around it.

Take a look at unary_function for inspiration. There they use template traits to transfer type parameters without using any magic:

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

'unary_function' contains no function other than declaration of typedefs. However, these typedefs allow you to express equivalents between code segments in code and during compilation. They use a way to check template parameters.

This means that you may have objects that work on this:

 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 ); } }; 

which contains the value type of arguments inside it without specifying them in advance. Therefore, if you have pixel_type or something similar for each of your image objects, simply by specifying typename T::pixel_type , you will call the required type parameter.

+1
source

All Articles