-
conditional definition?
Hi,
I got the source code of a library. Its header file has following lines:
Code:
typedef int coord;
#define SIZE 8;
#define MYPOW(v) fabs(v)
I like to modify these definitions in a new function added to the header and recompile the library, so that I can call this function from my program to make "coord", "SIZE" and "MYPOW" defined in another way depending on some condition, something like
Code:
void definition(int i){
if (i > 0) {
typedef int coord;
#define SIZE 8
#define MYPOW(v) ((v)*(v)) }
else {
typedef double coord;
#define SIZE 16
#define MYPOW(v) fabs(v) }
}
I know this is not correct. Does C/C++ have something like conditional definition not using directives? Even if they do, how to make the symbols "coord", "SIZE" and "MYPOW" global, instead of being only effective within the function and not exiting outside?
For example, "coord" in the following code will not exist outside the function definition() and will not be available to use.
Code:
void definition(int i){
if (i>0) {typedef int coord ;}
else {typedef float coord ;}
}
For the function-like macro MYPOW, I can think of a way as
Code:
double (*MYPOW) (double);
double square(double v) {return ((v)*(v));}
void definition(int i){
if (i > 0) {MYPOW = &fabs;}
else {MYPOW = □}
}
Really appreciate your help!
Thanks and regards!
-
I suppose the C++ way would be to create a coord template, and create two instances of that (one int, one double)
A C way might be to create a union, like
Code:
typedef union {
int iCoord;
double dCoord;
} coord;
coord square(int i, coord c) {
coord result;
if ( i > 0 ) {
result.dCoord = fabs(c.dCoord);
} else {
result.iCoord = c.iCoord * c.iCoord;
}
return result;
}
-
You can do some template trickery.
Code:
template<int x> struct X {};
template<> struct X<1>
{
typedef int coord;
static coord pow(coord p) {return p*p;};
};
template<> struct X<2>
{
typedef double coord;
static coord pow(coord p) {return fabs(p);};
};
int main()
{
X<1>::coord p = X<1>::pow(2); // use the int version
X<2>::coord p = X<2>::pow(2.0); // use the double version
X<3>::coord p = X<3>::pow(2); // compiler will complain bitterly, as X<3> not instantiated
}
Yes, I realise there is no obvious "if" statement. But instantiated a template using a value is logically the same thing .... the only difference is that the compiler evaluates the condition, not your program.
-
Thanks!
But using either template or union will mean that modification is inevitable wherever the original symbols appear in the implementation of the library. Can I just leave the rest of code intact?
Now the function-like macro MYPOW can be replaced by global functional pointer that can be assigned in the function, and the numerical macro SIZE can be replaced by global integer that can also be assigned in the function. How can I do similarly to the type alias "coord"?
-
You miss the point. If you want to do selection of types within a library based on some conditions, your library code needs to be modified to handle new cases. There is no way around that, as C++ is a statically typed language.
Using a global function pointer to address this is, to put it gently, an ugly hack.