Search code examples
c++templatesc-preprocessorpreprocessor-directive

Use a template parameter in a preprocessor directive?


Is it possible to use a non-type constant template parameter in a preprocessor directive? Here's what I have in mind:

template <int DING>
struct Foo
{
    enum { DOO = DING };
};

template <typename T>
struct Blah
{
    void DoIt()
    {
        #if (T::DOO & 0x010)

        // some code here

        #endif
    }
};

When I try this with something like Blah<Foo<0xFFFF>>, VC++ 2010 complains something about unmatched parentheses in the line where we are trying to use #if. I am guessing the preprocessor doesn't really know anything about templates and this sort of thing just isn't in its domain. What say?


Solution

  • No, this is not possible. The preprocessor is pretty dumb, and it has no knowledge of the structure of your program. If T::Doo is not defined in the preprocessor (and it can't be, because of the ::), it cannot evaluate that expression and will fail.

    However, you can rely on the compiler to do the smart thing for you:

            if (T::Doo & 0x010) {
                // some code here
            }
    

    Constant expressions and dead branches are optimized away even at the lower optimization settings, so you can safely do this without any runtime overhead.