开发者

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?


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.


what members are available in T depends on which bits are set in T::DOO

It sounds to me like T::DOO is acting like a subclass identifier. So I'm thinking that your Foo and related classes should be subclasses of a class that guarantees that DOO is defined.

The key is: why must you use a bit field?


Not sure if this applies to your situation, but it is possible to isolate different cases with template classes. For example: (using a modified version of your code from above)

template <typename T, int N>
struct Blah
{
    void DoIt()
    {
        // normal DoIt() code
    }
};

template <typename T>
struct Blah<T,5>
{
    void DoIt()
    {
        // special DoIt() code for only when N==5
    }
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜