C++ Constant preprocessor macros and templates
So say I have the following very simple macro, along with a bit of code to output it:
开发者_StackOverflow中文版#define SIMPLEHASH(STRING) STRING[1] + STRING[2] + STRING[3]
std::cout << SIMPLEHASH("Blah");
This outputs 309, and if you view the assembly you can see:
00131094 mov ecx,dword ptr [__imp_std::cout (132050h)]
0013109A push 135h
0013109F call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (13203Ch)]
Where 135h
translates nicely into 309 decimal. Everything was compiled away to a constant.
Now, say you have a template class as such:
template<int X> class Printer{
public:
void Print(){
std::cout << X;
}
};
Then the following will nicely print the number 32:
Printer<32> p;
p.Print();
Both these things work individually, the problem comes when you try to combine them:
#define SIMPLEHASH(STRING) STRING[1] + STRING[2] + STRING[3]
Printer<SIMPLEHASH("Blah")> p;
p.Print();
In visual studio this gives:
1>.\ShiftCompare.cpp(187) : error C2975: 'X' : invalid template argument for 'Printer', expected compile-time constant expression
1> .\ShiftCompare.cpp(127) : see declaration of 'X'
Despite the fact that SIMPLEHASH("Blah")
can be reduced to a constant at compile time, as seen in the first example.
So, what gives, is there a way to tell the compiler "evaluate this first"? are templates naturally "before" macros in preprocessor evaluation?
Does anyone see any way I can get these two to work together?
Macros are evaluated before the source is fully parsed and preprocessing has nothing at all to do with templates.
The problem is that the template argument with which you instantiate Printer
must be a constant expression and you cannot use a string literal in a constant expression.
精彩评论