I'm storing images as arrays, templated based on the type of their elements, like Image<unsigned>
or Image<float>
, etc. Frequently, I need to perform operations on these images; for example, I might need to add two images, or square an image (elementwise), and so on. All of the operations are elementwise. I'd like get as close as possible to writing things like:
float Add(float a, float b) { return a+b; }
Image<float> result = Add(img1, img2);
and even better, things like
complex ComplexCombine(float a, float b) { return complex(a, b); }
Image<complex> result = ComplexCombine(img1, img2);
or
struct FindMax {
unsigned currentMax;
FindMax(): currentMax(0) {}
void operator(unsigned a) { if(a > currentMax) currentMax = a; }
};
FindMax findMax;
findMax(img);
findMax.currentMax; // now contains the maximum value of 'img'
Now, I obviously can't exactly do that; I've written something so that I can call:
Image<float> result = Apply(img1, img2, Add);
but I can't seem to figure out a generic way for it to detect the return type of the function/function object passed, so my ComplexCombine
example above is out; also, I have to write a new one for each number of arguments I'd like to pass (which seems inevitable).
Any thoughts on how to achieve this (with as little boilerplate code as possible)?