Common Interface to perform Detection algorithm - c++

I am stuck in a situation please help me out of this.
Thought:
To have a common Interface among different Detection algorithms(Say Circle, Triangle and Rectangle).
class IDetectionInterface()
{
public:
virtual void PerformDetection(Image & InputImage, DetectionStruct & DetectionData, DetectionParam & DetParam) = 0;
virtual ~IDetectionInterface()
{
}
};
where Image and DetectionStruct is a structure as below:
struct Image
{
unsigned char * pImageData;
int Width;
int Height;
};
struct DetectionStruct
{
Rect BoundingBox;
DectionType DetType;
};
struct Rect
{
int x;
int y;
int width;
int height;
};
enum DectionType
{
Circle = 0,
Triangle = 1,
Rectangle = 2
}
The Problem for me is that of DetectionParam, as Parameters of Detection Algorithms differ. Say for example
struct RectDetectionParam
{
int param1;
float param2;
double param3;
};
struct TriDetectionParam
{
float param1;
float param2;
double param3;
int param4;
};
struct CirDetectionParam
{
int param1;
float param2;
bool param3;
int param4;
float param5;
};
How can i get this to common interface as above.
Note: I don't want to put all the parameters in one structure which is a easiest solution, But it has its drawback if i change the algorithm then its respective parameters changes and we need to re write the structure again.
And Ofcource Yes, I will have the implementation of the interface(Abstract class)
Thanks in advance

Based on your example you could create a discriminated union to make the parameter sets generic:
struct DetectionParams {
DectionType detectionType; // Discriminator
union {
RectDetectionParam rectDect;
TriDetectionParam triDect;
CirDetectionParam cirDect;
};
};
Which of the union parts is used in the implementation is determined by the discriminator.
Another way is to use something like a parameter set based on unique parameter names (key strings):
struct DetectionParams {
std::map<std::string,std::any> params; // Note that std::any is available
// at the not yet official c++17 standard
};

Related

How to handle composite type in a template class

I have the following template class definition: a typical Matrix class -
template<typename T>
class Matrix
{
std::vector<Array<T>> m_rows;
uint32_t m_M;
uint32_t m_N;
bool m_container;
public:
Matrix() : m_rows{}, m_M(0), m_N(0), m_container(true) { }
Matrix(uint32_t width, uint32_t height, T val, uint32_t strideX=0, uint32_t strideY=0) :
m_rows(std::max(strideY, height), Array<T>(width, T{}, strideX)),
m_M(width), m_N(height), m_container(false)
{
for(uint32_t row=0; row < height; row++)
{
m_rows[row] = val;
}
}
//more class methods, not relevant to this discussion
Code in main():
int main()
{
typedef struct { float a; float b; } MyStruct;
MyStruct val = { 1.0, 2.0 };
Matrix<MyStruct> m(3,3,val); //so, define a 3x3 matrix with 'val' struct as constant value
}
The Matrix will try to initialize the std::vector<> container with T{} entries.
To my surprise, this worked! So, my next question is, WHY does T{} work? Is this the C++ way to 'cast' literals to the 'T' type, even if 'T' is composite?
thanks, Charles
It's because you are using MyStruct only. Since MyStruct can be initialized with {}, it can be compiled.
But if you have other classes that cannot be initialized with a default constructor, it can't be compiled.
struct foo{};
class faa{
public:
fee(int x){}
};
In this case,
Matrix<foo>
can be compiled, while
Matrix<faa>
cannot.

Define dynamic struct

I want to define a structure with different variable type in some field. for example i define a struct like this:
struct sensor {
int index;
int value;
};
struct sensor2 {
int index;
float value;
};
i want to declare only one structure with two option, someone integer value and other time float value, but in unique structure.
My question is :
1.there are anyway to declare one structure and pass parameter to chose one of type (int or float or ...)?
2. can i use template for this reason?
struct sensor {
int index;
type_as_option value; //int or float
};
thank for your aid with best regard
You have several options. You could make it a template:
template <typename T>
struct sensor {
int index;
T value;
};
However, if you want the two structs being the same type, this is not what you are looking for, as
sensor<int>
and
sensor<float>
are two different types.
Second option is (as immibis pointed out in a comment) to simply make a struct with both
struct sensor {
int index;
int ivalue;
float fvalue;
};
However, this introduces almost 50% memory overhead that can be avoided by using a union:
union intOrFloat {
int ivalue;
float fvalue;
};
struct sensor {
int index;
intOrFlaot value;
};
Of the union always only one field is active and it doesnt use more memory than necessary.

Redundancy of structures

I'd like to get some opinion from more experienced programmers. I have a structure like:
struct Position {
int x;
int y;
};
but I need to store for example longitude in a structure like:
struct Longitude {
int from;
int to;
};
both of them are actually the same with different names, but x and y are misleading in the case of Longitude. Would you use some typedef Position Longitude instead of defining Longitude structure (but then we have x/y there...)? Or create the same redundant structure with another names? Or maybe there are other alternatives?
I'd be inclined to keep them separate.
In C++ a struct and a class are identical constructs (excepting the default access of member variables and functions).
As your application evolves, you'll probably want to add more functions and member data to the structs. At that point the two definitions will start to diverge. Keeping them separate from the outset will assist this development.
If you're concerned about code duplication then you can always inherit from a base class or struct.
I think, if it is feasible, I would store it internally as either x/y or from/to and provide a public accessible interface for conversion.
How about this?
struct Position {
int x;
int y;
};
using Longitude = Position;
c++11 provides such sugar sintax, you have the same data with other name (you still have the same x/y stuff, but I dont really see the trouble of using them.)
I would make Position class parent of Longitude and user getters and setters instead bare attributes:
class Position {
public:
int getX() { return x; }
int getY() { return x; }
void setX(int x) { this->x = x; }
void setY(int y) { this->y = y; }
protected:
int x;
int y;
};
class Longitude : public Position {
public:
int getFrom() { return getX(); }
int getTo() { return getY(); }
void setFrom(int from) { setX(from); }
void setTo(int y) { setY(to); }
}

How to pass a union as a function parameter without defining it first?

Is it possible define a union temporary inside the function call, rather than defining it previously and then passing it in the parameters?
Example:
union data_t{
double delaySeconds;
float scale;
float rotation;
};
void someFunction(data_t){}
Now I want to call someFunction, using whatever element of the union is appropriate:
someFunction(WHAT DO I PUT HERE);
For example, if you are passing to a function that expects a type that includes a constructor, you can define your temporary right there in the function call. But I've tried a variety of ways with this union with no luck. For example, suppose I want to pass a float assigned to scale:
someFunction(data_t.scale(2.0));
You can define a constructor for your union for initializing the members. But, you need a mechanism to distinguish which field was set. Below, I define a helper enum, and extend your data_t to allow for inheritance and member distinction.
enum data_t_type { DelaySeconds, Scale, Rotation };
struct data_t {
union {
double delaySeconds;
float scale;
float rotation;
};
union {
unsigned char flags;
struct {
unsigned char isDelaySeconds : 1;
unsigned char isScale : 1;
unsigned char isRotation : 1;
};
};
data_t () : flags(0) {}
};
Now, the initialization is actually done with a template that takes the data_t_type as a parameter.
template <data_t_type> struct data_type {};
template <> struct data_type<DelaySeconds> : data_t {
data_type (double x) { delaySeconds = x; isDelaySeconds = 1; }
};
template <> struct data_type<Scale> : data_t {
data_type (float x) { scale = x; isScale = 1; }
};
template <> struct data_type<Rotation> : data_t {
data_type (float x) { rotation = x; isRotation = 1; }
};
So now, you can call your function like so:
someFunction(data_type<Scale>(2.0));
Since a data_type<> is a data_t, someFunction() gets the right type.

C++: Differences between using Structs or Enums for overloading constructors?

I can use either a struct or an enum to overload constructors, and they both seem to do the same job. in fact, changing from one to the other doesn't even show any differences when diff'ing the two executables using each. But, which is proper?
This:
enum PointLocalCoord{ local };
enum PointGlobalCoord{ global };
class Point {
Point( const PointLocalCoord, const int x, const int y )
{ /* something */ }
Point( const PointGlobalCoord, const int x, const int y )
{ /* something else */ }
};
or This:
struct local{};
struct global{};
class Point {
Point( const local, const int x, const int y )
{ /* something */ }
Point( const global, const int x, const int y )
{ /* something else */ }
};
Neither is good. You should have strongly semantic types, even for quantities of the same dimension, and conversion functions between them:
struct LocalPoint { int x; int y; };
struct GlobalPoint { int x; int y; };
LocalPoint getLocal(GlobalPoint const & gp) { /* remainder? */ }
GlobalPoint getGlobal(LocalPoint const & lp, int offset_x, int offset_y);
Now you can make constructors for each point type directly.
The upshot here is that a semantic point class is much better than two random, meaningless integers.
Both work in the sense that they compile, but you should choose one based on logic. In your case, I'm thinking it should be an enum, but slightly different:
enum PointCoordType
{
local,
global
};
class Point {
Point( PointCoordType, const int x, const int y )
{ /* something */ }
};
Or even having two types of Point classes:
LocalPoint : Point
and
GlobalPoint : Point