假设我有以下非常简单的宏,以及一些输出该宏的代码:
#define SIMPLEHASH(STRING) STRING[1] + STRING[2] + STRING[3]
std::cout << SIMPLEHASH("Blah");
这将输出309,如果您查看汇编代码,您会看到:
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)]
其中135h
很好地翻译成了309十进制。所有内容都被编译为一个常量。
现在,假设您有一个如下的模板类:
template<int X> class Printer{
public:
void Print(){
std::cout << X;
}
};
接下来的代码将会输出数字32:
Printer<32> p;
p.Print();
这两个东西单独使用都没问题,但当你试图将它们结合起来时会出现问题:
#define SIMPLEHASH(STRING) STRING[1] + STRING[2] + STRING[3]
Printer<SIMPLEHASH("Blah")> p;
p.Print();
在Visual Studio中,这将产生以下结果:
尽管在第一个示例中可以将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'
SIMPLEHASH("Blah")
简化为编译时常量。但是,仍然会出现上述错误。那么问题来了,有没有一种方法告诉编译器“先评估这个”?模板在预处理器评估中自然比宏“先”吗?
有没有人看到任何我可以让这两者共同工作的方法?
"Blah"[0]
不是一个常量表达式;就是这样。仅仅因为你的编译器碰巧能够解决它,并不意味着任何事情。(这就是采用特定于实现的结果并假设它被语言保证的问题所在。) - GManNickG