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
}
};
精彩评论