ulf
ulf

Reputation: 190

C++ preprocessor

I would like to conditionally include functions (or specifically constructors) depending on a variable type I define on the level of the preprocessor, e.g.

#define my_type double

and at any point I can conditionally include a function

#if my_type == double
void my_fct();
#endif

which works fine. However, how do I do this if I want to assign a templated type to my_type. Using complex double for example, I would naively ave thought

#if my_type == complex<double>

would work, but the preprocessor seems to interpret the last ">" as an operator on the preprocessor level. I don't see a way to use typedefs, since I want the preprocessor perform the conditional inclusion. Of course I could template my entire class and avoid using the preprocessor for this task, but I would currently very much prefer not to. Also, one could always define another preprocessor flag in addition to the type, but this seems rather dirty.

Upvotes: 2

Views: 188

Answers (4)

tgmath
tgmath

Reputation: 13531

Similar ideas as @Debasish-Jana: use as typtdef and template functions, this is a bit ugly looking:

type typedef double my_type;

And a function for the double case:

template<typename T = my_type>
typename std::enable_if<std::is_same<T,double>::value, void>::type 
cnt() 
{

}

And another or the cmplex numbers:

template<typename T = my_type>
typename std::enable_if<std::is_same<T,std::complex<double>>::value, void>::type 
cnt() 
{

}

An example is here: https://ideone.com/aXupSa . Having tried this, I wonder why I would write Code like this. Nice and pretty is something else.

Upvotes: 0

Dr. Debasish Jana
Dr. Debasish Jana

Reputation: 7118

What about a full fledged template like:

template <class T>
void my_fct() {
 // your code based on T as a type
}

And, you call as: my_fct<int>, my_fct<double> etc to pass in the data type for appropriate template instantiation.

Upvotes: 0

Sebastian Redl
Sebastian Redl

Reputation: 71899

I am very surprised that my_type == double works; it definitely shouldn't. The preprocessor can only evaluate simple numeric expressions.

So the answer is no, you can't work with template types (the preprocessor doesn't know about types, it just does token substitution). If you want logic on the type level, you need templates.

Upvotes: 1

M.M
M.M

Reputation: 141544

#if my_type == double does not test whether you have done #define my_type double. In fact it will always be true .

In the preprocessor arithmetic you can only use integer constant expressions, so you will have to set something up like:

// from your makefile or whatever
#define MY_TYPE MY_DOUBLE

...

// in header file
#define MY_INT 3
#define MY_DOUBLE 4
#define MY_COMPLEX_DOUBLE 5

#if MY_TYPE == MY_DOUBLE
    typedef double my_type;
#elif MY_TYPE == MY_INT
    typedef int my_type;
#elif MY_TYPE == MY_COMPLEX_DOUBLE
    typedef complex<double> my_type;
#endif

Upvotes: 8

Related Questions